Официальный сайт компании Arduino по адресу arduino.cc
чего то делаю не так
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Втр, 17/10/2017 - 13:16
Большая просьба помочь, не кидая камнями. Программированием не занимался никогда. Делаю счетчик для горячей и холодной воды. (ну еще семисегментный 8 рарядный индикатор показывает время и температуру)
Не работает функционал записи значений в память (для сохранения на случай пропадания питания).
Ниже код, все лишнее выбросил (про индикатор, время и температуру). Проблемный кусок про EEPROM откуда то списал не разобравшись как работает :-(
И да... счетчик Cold работает как требовалось.
#include <Bounce2.h> // библиотека обработки дребезга контактов #include <avr/eeprom.h> // библиотека для работы с энергонезависимой памятью int inputColdPin = 8; //назначаем вывод 8 для холодного счетчика int inputHotPin = 7; //назначаем вывод 7 для горячего счетчика unsigned long Cold; unsigned long Hot; Bounce bouncer = Bounce(); Bounce bouncer2 = Bounce(); void setup() { //если хотим присвоить начальные значения, активируем следующие 4 строки //Cold=77419; //Hot=69539; //eeprom_write_block(&Cold, 0, 4); //eeprom_write_block(&Hot, 5, 4); //послезагрузки, вновь их деактивируем начальные значения будут сохранены eeprom_read_block(&Cold, 0, 4); eeprom_read_block(&Hot, 5, 4); // назначенные выводы для подсчета импульсов и подключаем их (с нагрузочными резисторами) к библиотеке антидребезга pinMode(inputColdPin, INPUT_PULLUP); pinMode(inputHotPin, INPUT_PULLUP); bouncer.attach(inputColdPin); bouncer2.attach(inputHotPin); bouncer.interval(10); // interval in ms bouncer2.interval(10); // interval in ms Serial.begin(9600); // инициализируем порт, скорость 9600 } void loop() { if (bouncer.update() && bouncer.read() == LOW) { Cold=Cold+1;eeprom_write_block(&Cold, 0, 4); delay(5); //запись нового значения в память } if (bouncer2.update() && bouncer2.read() == LOW) { Hot=Hot+1;eeprom_write_block(&Hot, 5, 4); delay(5); //запись нового значения в память } Serial.print("Hot: "); Serial.print(Hot);Serial.print("\t");Serial.print("Cold: "); Serial.println(Cold); }
А надо-то чо?
Добавлю: Считаю имульсы (1 на 10 литров), а на индикатор вывожу кубометры, а то разрядов не хватает.
Начальные, значения в коде - реальные, поэтому
unsigned
long
В приведенном коде, после закомментирования начальных значений, значение "Hot", после перезагрузки получается 1126318, а должно было быть 69539 С переменной "Cold" все в порядке
В коде проблем не вижу. должно работать. Попробуйте сохранять Cold в еепроме по другому адресу, например 10. Может у вас первые ячейки еепром "битые"
Попробуйте сохранять Cold в еепроме по другому адресу, например 10. Может у вас первые ячейки еепром "битые"
Это ненадолго с таким режимом записи.
2ТС: если бы вы свои Serial.print-ы воткнули сразу после считывания блока с eeprom, то всем было бы проще.
Ну Serial.print-ы воткнул в конце, что бы убедиться, счетчик считает и после сброса питания восстанавливаются именно насчитанные значения
А что с режимом записи не так? одна единичка счета на 10 литров это не особо много и часто. на 100 000 циклов это должно быть 1000 кубов (сейчас на счетчиках - 700 кубов)
Проблема не в "битых" ячейках - проверял на разных экземплярах Nano
Ну Serial.print-ы воткнул в конце, что бы убедиться, счетчик считает и после сброса питания восстанавливаются именно насчитанные значения
Проверил
Все работает, то есть счетчики после перезагрузки питания начинают считать с того места где остановились.
НО! "Нот" - со своих непойми откуда взявшихся 1126318
Что тут посоветовать... пытайтесь локализовать проблемное место - например, втыкайте
Serial
.print(
"Hot: "
);
Serial
.print(Hot);
туда, где у вас +1 делается.Hot: 69539 Cold: 77419
А начальные значения закоменнтировали?
Смысл был залить скетч с начальными значениями, а потом его же, но уже не давая начальных значений (брать их из EEPROM)
А начальные значения закоменнтировали?
Я даже вставил в сообщение то, что заливал, чтобы сомнений не возникло. Но это не помогло...
А что с режимом записи не так? одна единичка счета на 10 литров это не особо много и часто. на 100 000 циклов это должно быть 1000 кубов (сейчас на счетчиках - 700 кубов)
Проблема не в "битых" ячейках - проверял на разных экземплярах Nano
Вы уверены. что ваш код пишет в епром только изменяющиеся данные? Я бы на всякий случай писал функцией update(). И что 700 кубов - их этот код уже "натикал", а потом начал глючить? тогда точно битые ячейки.
Чтобы сохранить епром подольше, не пишите все время в одно место, пишите со смещением при каждой записи. Если надо - распишу алгоритм подробно. Можно продлить жизнь епром в десятки раз.
Нет этот код не натикал 700 кубов, я с Ардуиной живу последний месяц только и у меня не бассейн :-).
Запись в EEPROM стоит после изменения значения счетчика (то есть нет изменения - нет записи)
Запись со смещением - интересная мысль, но пока должно хватать того что есть.
Последовал совету b707 - перенес начальный адрес с 5 на 10: eeprom_write_block(&Hot, 10, 4);
Вроде получилось !!!
Вроде получилось !!!
тогда точно битые ячейки...
Может вы их при тестировании "поджарили"?
тогда точно битые ячейки...
Может вы их при тестировании "поджарили"?
Видимо
Был момент, когда чтобы кнопку не нажимать я счетчик в цикл поставил
А уже потом вычитал про 100 000 ограничение
А 100 000 - это на ячейку или на весь модуль?
Я сейчас снесу начальные адреса, это должно помочь?
А 100 000 - это на ячейку или на весь модуль?
Я сейчас снесу начальные адреса, это должно помочь?
на ячейку.
счетчик в цикле - это круто. Где-то читал. что при записи в цикле флеш убивается за 7 секунд, а епром за минуту.
Сдвиньте адреса записи куда-нибудь подальше, например за сотню адресов , должно помочь.
Где-то читал. что при записи в цикле флеш убивается за 7 секунд, а епром за минуту.
Сдвиньте адреса записи куда-нибудь подальше, например за сотню адресов , должно помочь.
Спасибо сдвину :-)
Я ж новичок. Всех познаний програмировании: иф, зен, гоу ту. Мне про это в институте рассказывали, лет 30 назад :-)
Ну вроде все заработало.
Вот только индикатор заметно мерцает на температуре и времени, в чем может быть дело?
Я выложу весь скетч скопом, не судите строго. Вернее судите, но не строго:
может быть в LedControl.h
проблема?
что за индикаторы кстати?
Индикатор такой:
MAX7219 LED Dot Matrix 8-Digit Digital Tube Display Control Module
https://ru.aliexpress.com/item/MAX7219-LED-Dot-Matrix-8-Digit-Digital-Tube-Display-Control-Module/32654195774.html?spm=a2g0v.10010108.1000016.1.41fcc028CGYQCk&isOrigTitle=true
По идее не должно быть делло в библиотеке. Температуру я отдаю ей так же как и значения счетчиков.
Так у Вас lc.clearDisplay(0) на каждом прогоне loop (вызове Filer) для температуры и времени. Зачем??
Чтобы сохранить епром подольше, не пишите все время в одно место, пишите со смещением при каждой записи. Если надо - распишу алгоритм подробно. Можно продлить жизнь епром в десятки раз.
интересно , распишите, как Вы это делаете.
Я делал испыталку на вкл/выкл, и каждый факт срабатывания надо было хранить. А тестов в одном запуске 40000 раз.
Потому храню в ячейке с аддр 0 номер запуска (int), а текущий адрес для записи результатов тестов каналов (4*unsigned int) в запуске вычисляю каждый раз, как :
текущий_адрес=базовый_адрес+количество_запусков*длина_записи(+смещение_канала)
если результат больше 1023, то текущий_адрес=базовый_адрес
Так у Вас lc.clearDisplay(0) на каждом прогоне loop (вызове Filer) для температуры и времени. Зачем??
Если не чистить каша получается.
Но Вы правы. Поставил очистку на конкретные номера заходов на филер и все получилось :-)
Вот, получилось
Всем ОГРОМНОЕ спасибо.