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 то велики шансы на то, что проблема програмная.
Если число совсем некруглое получается - скорее всего проблема аппаратная - или кварц кривой, или паразитные емкости где-то имеются в цепи кварца (непропай?).
Нда.. правильно говорят, что утро вечера мудреенее. Сейчас попробовал заново скомпилить и залить. Все работает, моргает, как ожидалось, данные в порт пошли в нормальном виде... что это было - так и не понял. Железо не менял.