Управляемая вводом переменная счетчика спорадически увеличивается, если определенные функции вызываются в Setup()
Я использую ATTiny84 на специальной печатной плате спиннера (схематическое изображение ниже), вдохновленной этой инструкцией. Я программирую его с помощью карманного программатора SparkFun AVR, ATTinyCore и адаптера с пого-пином. Датчик Холла не используется. Приведенный ниже код просто устраняет дребезг ввода с кнопки, которая продвигает переменную режима. Если переменная режима равна 7, код мигает 8 светодиодами таким образом, что при вращении прядильщика появляется рисунок кувшинки. Это написано для пинмэппинга против часовой стрелки.
Код работает, пока я не включу в настройку функцию blipLED(). Его вызов приводит к тому, что переменная режима периодически циклически повторяется, увеличиваясь нажатием кнопки или (чаще) прикосновением к металлическому предмету в цепи. Кто-нибудь знает, почему это может быть?
В приведенном ниже коде blipLEDs() в setup() закомментированы.
Спасибо,
Франклин
/*
LED test
*/
#ifdef PINMAPPING_CW
#error "Sketch was written for counterclockwise pin mapping!"
#endif
#include <EEPROM.h>
int LEDS[] = {10, 9, 8, 7, 6, 5, 4, 3}; // Порт А против часовой стрелки
//int LEDS[] = {0, 1, 2, 3, 4, 5, 7, 6}; // Порт А по часовой стрелке
// константы не изменятся. Они используются здесь для установки номеров контактов:
const int buttonPin = 0; // номер вывода кнопки
// Переменные изменятся:
int buttonState = HIGH; // текущее чтение с входного вывода
int mode = 0; // текущий выбранный светодиод для мигания
int modes = 8; // количество доступных светодиодов
int lastButtonState = HIGH; // предыдущее чтение с вывода кнопки ввода
// следующие переменные являются беззнаковыми длинными, потому что время, измеренное в
// миллисекунды, быстро станет большим числом, чем может быть сохранено в int.
unsigned long lastDebounceTime = 0; // последний раз, когда выходной пин был переключен
unsigned long debounceDelay = 50; // время устранения дребезга; увеличить, если выход мерцает
void setup() {
for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
pinMode(LEDS[LED], OUTPUT);
}
pinMode(buttonPin, INPUT_PULLUP); //включить внутренний подтягивающий резистор
// получить сохраненный режим из eeprom
mode = EEPROM.read(0);
if (mode >= modes) {
mode = 0; // первый раз может быть очень большим
}
digitalWrite(LEDS[mode], HIGH);
// вызов приведенного ниже приводит к тому, что переменная режима периодически циклически повторяется, увеличиваясь нажатием кнопки или (чаще) прикосновением к металлическому предмету на схеме)
//blipLEDs();
}
// функция цикла запускается снова и снова навсегда
void loop(){
checkButton();
if (mode == 7) {
lilyPad();
}
}
void lilyPad() {
for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
digitalWrite(LEDS[LED], HIGH);
delay(1);
digitalWrite(LEDS[LED], LOW);
}
for(int LED=(sizeof(LEDS)/sizeof(int))-1; LED >= 0; LED--){
digitalWrite(LEDS[LED], HIGH);
delay(1);
digitalWrite(LEDS[LED], LOW);
}
}
void blipLEDs(){
// что-то, чтобы показать, что мы живы
for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
digitalWrite(LEDS[LED], HIGH);
delay(10);
digitalWrite(LEDS[LED], LOW);
}
for(int LED=sizeof(LEDS)/sizeof(int); LED>mode; LED--){
digitalWrite(LEDS[LED], HIGH);
delay(10);
digitalWrite(LEDS[LED], LOW);
}
digitalWrite(LEDS[mode], HIGH);
}
void checkButton() {
// прочитать состояние переключателя в локальную переменную:
int currentButtonState = digitalRead(buttonPin);
// проверяем, не нажали ли вы кнопку только что
// (т.е. вход изменился с ВЫСОКОГО на НИЗКИЙ), и вы ждали достаточно долго
// с момента последнего нажатия, чтобы игнорировать любой шум:
// Если переключатель становится НИЗКИМ из-за шума или нажатия:
if (currentButtonState != lastButtonState) {
// сброс таймера устранения дребезга
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// каким бы ни было чтение, оно было там дольше, чем устранение дребезга
// задержка, так что примите это как фактическое текущее состояние:
// если состояние кнопки действительно изменилось (а не просто шум):
if (currentButtonState != buttonState) {
//устанавливаем состояние кнопки
buttonState = currentButtonState;
//режим увеличения только в том случае, если состояние новой кнопки НИЗКОЕ
if (buttonState == LOW) {
mode += 1;
// если режим больше или равен общему количеству светодиодов, сбросить режим на 0
if (mode >= modes) {
mode = 0;
}
EEPROM.write(0, mode);
blipLEDs();
}
}
}
// Сохраняем текущее чтение кнопки. В следующий раз в цикле это будет последнее состояние кнопки.
lastButtonState = currentButtonState;
}
@fmarquet, 👍-1
Обсуждение1 ответ
Второй цикл в blipLEDs()
начинается с индекса "отклонение на единицу":
for(int LED=sizeof(LEDS)/sizeof(int); // ...
Поскольку он записывается на какой-то пин, это зависит от содержимого доступной памяти, на какой пин записывается. Это может быть контакт кнопки, поскольку его индекс равен "0".
- Проблемы с загрузкой кода в ATTiny84 с помощью Sparkfun AVR Pocket Programmer и ATTinyCore
- avrdude: ошибка проверки, первое несоответствие в байте 0x0000 : 0x00 != 0x16 с использованием USBasp
- Arduino IDE не будет использовать выбранный порт
- avrdude ser_open() can't set com-state
- При использовании Arduino Uno в качестве ISP: "Yikes! Invalid device signature" - плохое соединение, неверную конфигурацию или неверную версию avrdude?
- ATtiny85 и DHT11 - Датчик всегда возвращает 0
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
- Где параметры avrdude определяются в Arduino IDE?
Я бы начал отлаживать эту проблему, пытаясь сделать максимально простую версию программы, а затем добавлять обратно код/функции до тех пор, пока она не перестанет работать — обычно это проясняет, в чем проблема. В этом случае, возможно, попробуйте обрезать программу до тех пор, пока, скажем, вы не сможете просто нажать кнопку, чтобы перейти в режим увеличения, а также показать текущий режим, просто зажигая светодиод (без вращения или eeprom) и посмотреть, работает ли это. Затем попробуйте добавить только сохранение/загрузку eeprom и посмотрите, что произойдет. Сообщите, что вы найдете!, @bigjosh