atmega168 работает как-то странно
- Войдите на сайт для отправки комментариев
Есть одна железка: http://www.seeedstudio.com/wiki/Dragrove (кратко: роутер, с доп.платой на атмега168).
На атмегу можно заливать прошивки (через ssh). И вроде как, изображает что работает (сейчас поясню).
Прошивки предварительно генерятся с помощью Ардуино IDE (выбираю, конечно, дуемиланову атмега168: результат работы - hex-файл). Дальше этот файл как раз заливается в МК.
В конфигурации "заливальщика" в явном виде прописаны фьюзы:
AVR_PART=atmega168 # AVR part
EFUSE=0x01
HFUSE=0xdd
LFUSE=0xff
И, судя по процессу, который виден через SSH при заливке прошивки в МК - все отрабатывается верно:
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.01s avrdude: Device signature = 0x1e9406 avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "serial_test.cpp.hex" avrdude: input file serial_test.cpp.hex auto detected as Intel Hex avrdude: writing flash (4388 bytes): Writing | ################################################## | 100% 4.78s avrdude: 4388 bytes of flash written avrdude: verifying flash memory against serial_test.cpp.hex: avrdude: load data flash data from input file serial_test.cpp.hex: avrdude: input file serial_test.cpp.hex auto detected as Intel Hex avrdude: input file serial_test.cpp.hex contains 4388 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 4.41s avrdude: verifying ... avrdude: 4388 bytes of flash verified avrdude: reading input file "0x01" avrdude: writing efuse (1 bytes): Writing | ################################################## | 100% 0.00s avrdude: 1 bytes of efuse written avrdude: verifying efuse memory against 0x01: avrdude: load data efuse data from input file 0x01: avrdude: input file 0x01 contains 1 bytes avrdude: reading on-chip efuse data: Reading | ################################################## | 100% 0.00s avrdude: verifying ... avrdude: 1 bytes of efuse verified avrdude: reading input file "0xdd" avrdude: writing hfuse (1 bytes): Writing | ################################################## | 100% 0.00s avrdude: 1 bytes of hfuse written avrdude: verifying hfuse memory against 0xdd: avrdude: load data hfuse data from input file 0xdd: avrdude: input file 0xdd contains 1 bytes avrdude: reading on-chip hfuse data: Reading | ################################################## | 100% 0.01s avrdude: verifying ... avrdude: 1 bytes of hfuse verified avrdude: reading input file "0xff" avrdude: writing lfuse (1 bytes): Writing | ################################################## | 100% 0.00s avrdude: 1 bytes of lfuse written avrdude: verifying lfuse memory against 0xff: avrdude: load data lfuse data from input file 0xff: avrdude: input file 0xff contains 1 bytes avrdude: reading on-chip lfuse data: Reading | ################################################## | 100% 0.01s avrdude: verifying ... avrdude: 1 bytes of lfuse verified avrdude: safemode: Fuses OK avrdude done. Thank you.
Повторюсь, скетчи заливаются. Но есть какая-то странная засада.
Пример:
#include <SoftwareSerial.h> // SoftwareSerial mySerial(6, 7); //PD6 and PD7 are connected to Dragino UART port. #define COLD_RST 4 #define LED A2 int value1 = 1; int value2 = 2; void setup() { pinMode(COLD_RST, OUTPUT); digitalWrite(COLD_RST,LOW); pinMode(LED, OUTPUT); digitalWrite(LED,LOW); // set the data rate for the NewSoftSerial port mySerial.begin(9600); } void loop() // run over and over again { mySerial.print("<sensor3>"); mySerial.print(value1); mySerial.print(" <water>"); // an extra space between different value pair. mySerial.println(value2); value1++; if (value1 == 254) value1 = 1; value2 = value2+2; delay(1000); digitalWrite(LED,!digitalRead(LED)); }
Комментарии: COLD_RST - этот пин надо "прижать к земле" (иначе роутер просто не стартанет - этим пином можно роутер ребутать), на LED - повесил светодиод, чтобы видеть, что скетч работает.
Вполне (разумно?) ожидаю, что светодиод будет 1 секунду светиться и 1 секунду - нет.
А вот результат - слегка обескураживает. Светодиод моргает, но явно чаще ожидаемого (примерно вдвое), при этом моргание какое-то неравномерное (иногда бывают какие-то "подвисания" - паузы чуть больше "соседних" и т.п.).
Светодиод решил повесить, когда не смог увидеть данные, которые должны вылетать в SoftwareSerial (вместо них улетают какие-то крокозябры - аналогичная ситуация наблюдается в СериалМониторе, когда неверно выставлена скорость). Причем, порт, который надо слушать внутри роутера определен верно (/dev/ttyS0) и его скорость настроена (stty 9600 -F /dev/ttyS0).
Куда копать? Почему такое может быть?
Когда увидел "неравномерность" - подумал, что фьюзы предлагают атмеге работать на внутреннем осцилляторе, но нет, по фьюзам - это нормальная работа атмеги 168 на внешнем осцилляторе (резонатор на плате рассмотрел - 16МГц).
Что это? как диагностировать и лечить?
попробуйте убрать из loop все принты. Полагаю, мигать станет равномерно.
Тут проблема именно в том, что эти принты нужны (с их помощью ардуинка общается с роутером - там демон слушает и ждет именно этих данных). Понятно, что можно написать своего демона, но пока надо разобраться с тем, что есть "штатно".
Кстати, данные, которые печатает ардуинка - роутер дополнительно собирает в лог. Привожу его кусочек, чтобы было понятно, какой мусор туда летит:
Кстати, если убрать принты - моргать реже не станет...
А если библиотеку SoftwareSerial не подключать, диод с нормальной скоростью моргает?
мусор в логе может быть из-за того что порты на одном и на другом устройствах работают с разной скоростью. Теория: количество мусора приблизительно пропорционально отношению скоростей; 20 символов превратились в 60 - значит на приёмнике скорость в три раза больше.
Если вам оченнь важна скорость мигания светодиода - засекайте сколько времени работали принты и уменьшайте на это число значение передаваемое в delay.
Скорость моргания светодиодом вообще не важна (это просто индикатор, который реально-то и не нужен). Важна скорость обмена.
Для того что бы убедиться что это именно проблема не стабильной работы генератора - нерабочий кварц, отсутствуют кондеры на кварце или еще чего, нужно бы воткнуть эту Атмегу168 в дуину Уну или Дуемиланову и посмотреть как она себя ведет. Если возможности этого сделать нет и предположить что камень не полумертвый, то второй вариант - запустить от внутреннего осцилятора:
И перепишу под вас:
Добаляете в bords.txt, запускаете IDE, заливаете в Дуину ArduinoISP, подключаете все как надо, выбираете программатор ArduinoISP, выбираете из списка плат ATmega168 8MHz, нажимаете Burn bootloader, если прошился без ошибок, значит фьзы прошиты (фьюзы и только фьзы, а не бутлоудер), далее открываете скейтч Blink, нажимаете Upload, если прошился без ошибок значит все норм, далее подключаете светодиод к SCK и смотрите мигает ли светодиод с переодичностью в 1 секунду (0,5 Гц), если мигает нормально не быстрее и не медленнее ,то все норм, можно копать дальше.
Если будет работать нормально, значит меняйте кварц, смотрите, проверяйте его обвязку, дорожки, в общем все что с ним связано.
Вообще-то действительно, все показывает на то, что реальная тактовая частота дуины больше той, на которую рассчитывает IDE
Я использовал следующий способ определять "на глаз" частоту работы контроллра:
Вырезаем все лишнее, оставляем только простой блинк с инетвалом 1с горит-1с не горит.
Причем, для чистоты эксперимента можно даже от digitalWrite отказаться, записывая уровни непосредственно в регистр.
Далее, запускаем скетч и берем в руки секундомер.
Отсчитываем, допустим 100 морганий светодиодом, смотрим сколько времени прошло.
Таким образом определяем, сколько реально длится интервал времени, который дуина считает секундой.
Идем в boards.txt и правим соответствующим образом F_CPU (или думаем, откуда взялась разница).
Причем, если соотношение реального и рассчетного времен выражается числами 1.25:1, 2:1, 2.5:1, 4:`1 или 5:1 то велики шансы на то, что проблема програмная.
Если число совсем некруглое получается - скорее всего проблема аппаратная - или кварц кривой, или паразитные емкости где-то имеются в цепи кварца (непропай?).
Нда.. правильно говорят, что утро вечера мудреенее. Сейчас попробовал заново скомпилить и залить. Все работает, моргает, как ожидалось, данные в порт пошли в нормальном виде... что это было - так и не понял. Железо не менял.