atmega168 работает как-то странно

ustas
Offline
Зарегистрирован: 12.03.2012

Есть одна железка: 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МГц). 

Что это? как диагностировать и лечить?

toc
Offline
Зарегистрирован: 09.02.2013

попробуйте убрать из loop все принты. Полагаю, мигать станет равномерно.

ustas
Offline
Зарегистрирован: 12.03.2012

Тут проблема именно в том, что эти принты нужны (с их помощью ардуинка общается с роутером - там демон слушает и ждет именно этих данных). Понятно, что можно написать своего демона, но пока надо разобраться с тем, что есть "штатно".

Кстати, данные, которые печатает ардуинка - роутер дополнительно собирает в лог. Привожу его кусочек, чтобы было понятно, какой мусор туда летит:

08-04-2013 00:05:58;   1F¤о­…ЊМ¦;Щ^›1F¤оZЎ:ш¦;Щ^›1F¤оZҐЉМ«мКҐ.,ЪF¤оZҐ;ш®ИеJнЅh„HыэUъKж«ИЭ^›1F¤оээ}}ыѕю«ИЭ^›1F¤оэ¤}:ш«дК®оҐ
08-04-2013 00:08:10;   1F¤оE¦яѕю«дЭ^·1F¤оээЄ_яѕю¦;Щ^»1F¤оZюхцтш¦Иэ®.*ЪЊH;!Stб¦ИЭ^›юхфц…о#bхъѕю«ИЭ^—юъИ
08-04-2013 00:09:12;   мF¤оэъъйjя¦ИЭ^[йы«ыэъЉ_яѕю«дЭ^_(Ў~ы+ЇJнВ«Ип®Wiяыэъъ_Я>ю«Ие®ыЉ„LF¤оJ„Jж«;№^[kы+ЇJ‹А«ИЭ^[+яыэЉ__я~ю¦;Щ^[kыsЇJ…В«мЭ^[«Ў~ы+ЇJ«Дю«ИЭ^Wлы«чэъ¤ЊМ¦ИЭюµЏ

Кстати, если убрать принты - моргать реже не станет... 

Evgen
Evgen аватар
Offline
Зарегистрирован: 10.06.2011

А если библиотеку SoftwareSerial не подключать, диод с нормальной скоростью моргает?

toc
Offline
Зарегистрирован: 09.02.2013

мусор в логе может быть из-за того что порты на одном и на другом устройствах работают с разной скоростью. Теория: количество мусора приблизительно пропорционально отношению скоростей; 20 символов превратились в 60 - значит на приёмнике скорость в три раза больше.

Если вам оченнь важна скорость мигания светодиода - засекайте сколько времени работали принты и уменьшайте на это число значение передаваемое в delay.

ustas
Offline
Зарегистрирован: 12.03.2012

Скорость моргания светодиодом вообще не важна (это просто индикатор, который реально-то и не нужен). Важна скорость обмена. 

maksim
Offline
Зарегистрирован: 12.02.2012

Для того что бы убедиться что это именно проблема не стабильной работы генератора - нерабочий кварц, отсутствуют кондеры на кварце или еще чего, нужно бы воткнуть эту Атмегу168 в дуину Уну или Дуемиланову и посмотреть как она себя ведет. Если возможности этого сделать нет и предположить что камень не полумертвый, то второй вариант - запустить от внутреннего осцилятора:

ATmega168.name=ATmega168 8MHz

ATmega168.bootloader.low_fuses=0xE2
ATmega168.bootloader.high_fuses=0xDD
ATmega168.bootloader.extended_fuses=0xF9
ATmega168.bootloader.unlock_bits=0x3F
ATmega168.bootloader.lock_bits=0x0F
ATmega168.build.mcu=atmega168
atmega168.upload.maximum_size=16384
ATmega168.build.f_cpu=8000000L
ATmega168.build.core=arduino
ATmega168.build.variant=standard

И перепишу под вас:

Добаляете в bords.txt, запускаете IDE, заливаете в Дуину ArduinoISP, подключаете все как надо, выбираете программатор ArduinoISP, выбираете из списка плат ATmega168 8MHzнажимаете Burn bootloader, если прошился без ошибок, значит фьзы прошиты (фьюзы и только фьзы, а не бутлоудер), далее открываете скейтч Blink, нажимаете Upload, если прошился без ошибок значит все норм, далее подключаете светодиод к SCK и смотрите мигает ли светодиод с переодичностью в 1 секунду (0,5 Гц), если мигает нормально не быстрее и не медленнее ,то все норм, можно копать дальше.

Если будет работать нормально, значит меняйте кварц, смотрите, проверяйте его обвязку, дорожки, в общем все что с ним связано.

tsostik
Offline
Зарегистрирован: 28.02.2013

Вообще-то действительно, все показывает на то, что реальная тактовая частота дуины больше той, на которую рассчитывает IDE

Я использовал следующий способ определять "на глаз" частоту работы контроллра:

Вырезаем все лишнее, оставляем только простой блинк с инетвалом 1с горит-1с не горит.

Причем, для чистоты эксперимента можно даже от digitalWrite отказаться, записывая уровни непосредственно в регистр.

Далее, запускаем скетч и берем в руки секундомер.

Отсчитываем, допустим 100 морганий светодиодом, смотрим сколько времени прошло.

Таким образом определяем, сколько реально длится интервал времени, который дуина считает секундой.

Идем в boards.txt и правим соответствующим образом F_CPU (или думаем, откуда взялась разница).

Причем, если соотношение реального и рассчетного времен выражается числами 1.25:1, 2:1, 2.5:1,  4:`1 или 5:1 то велики шансы на то, что проблема програмная.

Если число совсем некруглое получается - скорее всего проблема аппаратная - или кварц кривой, или паразитные емкости где-то имеются в цепи кварца (непропай?).

ustas
Offline
Зарегистрирован: 12.03.2012

Нда.. правильно говорят, что утро вечера мудреенее. Сейчас попробовал заново скомпилить и залить. Все работает, моргает, как ожидалось, данные в порт пошли в нормальном виде... что это было - так и не понял. Железо не менял.