Ви не увійшли.
Оскільки на практиці виявилось не зручно заливати в nano по черзі то ArduinoOWISP.hex то OWSerialMaster.hex (до того ж і кількість перезаписів не безмежна), то вбудував функціонал OWSerialMaster в код ArduinoOWISP. Тепер достатньо залити в nano один раз ArduinoOWISP і можна про неї (nano) забути - для заливки прошивки в pro-mini і для монітора порта достатньо лише двох команд:
avrdude -P /dev/ttyUSB0 -b 19200 -c avrisp -p m328p -U flash:w:HelloWorld.hex
minicom -D /dev/ttyUSB0 -b 19200
Після запуску мінікома чекаєм пару секунд, натискаєм клавішу Enter (або Ctrl+M) і ще через пару секунд бачимо наш вивід з pro-mini.
UPD: змінив швидкість з 9600 на 19200, щоб в Arduino IDE не доводилось виправляти ніякі системні файли.
Інструкція для тих, хто користується Arduino IDE
1. В Arduino IDE створити новий скетч, додати в нього код ArduinoOWISP.ino, вибрати: Інструменти->Плата: "Arduino Nano" і натиснути "Вивантажити". Цей скетч нам більше не знадобиться, можна закрити.
2. Зібрати схему, як на малюнку в першому пості.
3. Створити новий скетч, написати свій код з використанням OWSerial (звичайно встановити бібліотеки OWSerial, DS2450, OneWire).
4. Вибрати: Інструменти->Плата: "Arduino Pro or Pro Mini", вибрати: Інструменти->Програматор: "Arduino as ISP" і натиснути Скетч->"Вивантажити за допомогою програматора". Скетч буде завантажуватися в pro-mini по 1-wire.
5. Вибрати: Інструменти->Монітор послідовного порту, у новомі вікні внизу вибрати "Повернення каретки (CR)", "19200 бод" і натиснути "Надіслати", через пару секунд почнеться вивід.
Тепер щоразу після редагування скетчу просто натискаєм Скетч->"Вивантажити за допомогою програматора", після закінчення вивантаження у вікні монітора порта натискаєм "Надіслати" і через пару секунд знову бачимо вивід.
UPD: для тих, хто використовує майстер шини на DS2480B, у пункті 1 перед вивантаженням треба знайти в скетчі ArduinoOWISP.ino стрічку "#define HAVE_DS2480B 0" і замінити 0 на 1. Необхідні бібліотеки завантажити звідси.
Якщо при вивантаженні свого скетчу отримуєм помилку:
avrdude: Yikes! Invalid device signature.
То, скоріш за все, забули в ArduinoOWISP.ino замінити адресу модуля розширення портів на свою, шукаєм таку стрічку і міняєм:
byte addr[] = {0x20,0x41,0x42,0x0F,0x48,0x4E,0x59,0x49};
Просканувати шину 1-wire і дізнатися адреси всіх пристроїв на ній можна за допомогою простого скетчу (завантажувати його потрібно в nano):
#include <OneWire.h>
OneWire ow(10);
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
byte i, addr[8];
if (!ow.search(addr)) {
Serial.println("No more addresses.");
ow.reset_search();
delay(5000);
return;
}
Serial.print("ROM =");
for (i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
Serial.println();
}
Описана вище технологія віддаленої прошивки і монітора порта дозволяє мати на одній шині 1-wire багато плат розширювача портів + pro-mini і працювати з кожною індивідуально.
Лайк за спробу відняти шматок хліба у розробників UPDI. Взяли б контроллер з нової лінійки Attiny 0-,1-,2- series і не мучались.
Це вийшло випадково))) Перша версія розширювача портів просто повторювала DS2450 (АЦП і gpio) плюс зовсім прості додаткові фішки, але залишалось ще трохи місця в памяті програм, тому придумував, що ще цікавого додати. Памяті вистачило лише на SPI, щоб можна було підключити датчик з SPI інтерфейсом (в планах є окремий пристій 1wire_slave -> I2C_master, типу DS28E17). Те, що можна дистанційно прошивати AVR, я вже збагнув трохи пізніше. А в OWSerial потреба виникла в процесі вирішення іншої задачі.
Якщо порівнювати це рішення з UPDI:
* дозволяє створити канал комунікації з програмою на м/к і писати на ньому свої датчики і пристрої (UPDI лише для прошивки)
* дозволяє використовувати одну шину для багатьох таких пристроїв ще й одночасно з іншими датчиками (UPDI - лише точка-точка)
* що у UPDI з відстанню роботи? 1-wire працює на 100-300м
Ще раз. Я ні на що не претендую, те що вийшло - вийшло випадково і на мою думку цікаво. Якщо підходить/подобається - користуйтесь.
Лайк за спробу відняти шматок хліба у розробників UPDI. Взяли б контроллер з нової лінійки Attiny 0-,1-,2- series і не мучались.
До заголовку можна ще додати ... та віддалений монітор порта.
Оскільки знадобилося якось бачити те, що виводить Serial.print() на віддаленій pro-mini, то написав бібліотеку OWSerial, яка дозволяє по 1-wire емулювати послідовний порт для програми.
В скетчі знадобиться замінити всі Serial. на OWSerial. додати #include <OWSerial.h> та замінити Serial.begin(9600); на OWSerial.begin();
Наприклад, скетч HCS301.ino, який я постив у сусідній темі, віглядатиме так:
#include <OWSerial.h>
#define HCS301_TE 400
#define HCS301_BITS 66
typedef struct {
uint32_t SerialNum;
uint32_t Encrypted;
uint8_t Btn1 :1;
uint8_t Btn2 :1;
uint8_t Btn3 :1;
uint8_t Btn4 :1;
uint8_t BatLow :1;
uint8_t Repeat :1;
} hcs301_t;
void hcs301_msg(hcs301_t *msg, uint8_t *a) {
msg->SerialNum = ((uint32_t)(a[7] & 0xf) << 24) | ((uint32_t)a[6] << 16) |
((uint32_t)a[4] << 8) | a[5];
msg->Encrypted = ((uint32_t)a[0] << 24) | ((uint32_t)a[1] << 16) |
((uint32_t)a[2] << 8) | a[3];
msg->Btn1 = (a[7] >> 5) & 1;
msg->Btn2 = (a[7] >> 6) & 1;
msg->Btn3 = (a[7] >> 7) & 1;
msg->Btn4 = (a[7] >> 4) & 1;
msg->BatLow = (a[8] >> 6) & 1;
msg->Repeat = (a[8] >> 7) & 1;
}
#define RF_RECV_PIN 2
#define is_roughly(d,t) ((d) > (t)-(t)/4 && (d) < (t)+(t)/4)
#define RF_TE HCS301_TE
#define RF_BITS HCS301_BITS
uint32_t RF_last_change = 0;
uint8_t RF_byte, RF_array[(RF_BITS+7)>>3];
uint8_t RF_mode = 0;
volatile boolean RF_catched = false;
void RF_interrupt() {
if (RF_catched)
return;
uint32_t duration = micros() - RF_last_change;
uint8_t pin = digitalRead(RF_RECV_PIN);
RF_last_change += duration;
if (!(RF_mode & 0x80)) {
if (RF_mode > 20 && pin == HIGH && is_roughly(duration, 10*RF_TE))
RF_mode = 0x80;
else if (!is_roughly(duration, RF_TE))
RF_mode = 0;
else if (!(RF_mode & 0x40))
RF_mode++;
} else {
uint8_t bit = 0;
if (is_roughly(duration, RF_TE))
bit = 0x80;
else if (!is_roughly(duration, 2*RF_TE))
RF_mode = 0;
if (RF_mode) {
if (pin == HIGH) {
if ((bit ^= RF_byte) & 0x80)
RF_mode++;
else
RF_mode = 0;
RF_byte >>= 1;
} else {
RF_byte |= bit;
RF_array[(RF_mode >> 3) & 0xf] = RF_byte;
if (RF_mode >= 0x80 + RF_BITS - 1) {
RF_catched = true;
RF_mode = 0;
}
}
}
}
}
void setup() {
OWSerial.begin();
attachInterrupt(digitalPinToInterrupt(RF_RECV_PIN), RF_interrupt, CHANGE);
OWSerial.println("Listening RF");
}
void loop() {
if (RF_catched) {
hcs301_t msg;
hcs301_msg(&msg, RF_array);
RF_catched = false;
OWSerial.print("#");
OWSerial.print(msg.SerialNum, HEX);
OWSerial.print(" ");
OWSerial.print(msg.Encrypted, HEX);
OWSerial.print(" ");
if (msg.Btn1) OWSerial.print("1");
if (msg.Btn2) OWSerial.print("2");
if (msg.Btn3) OWSerial.print("3");
if (msg.Btn4) OWSerial.print("4");
if (msg.BatLow) OWSerial.print(" BatLow");
if (msg.Repeat) OWSerial.print(" R");
OWSerial.println();
}
}
Щоб залити цей скетч на віддалену pro-mini, спочатку перетворюєм локальну nano (див. схему в першому повідомленні) в програматор ArduinoOWISP (перед компіляцією цього скетчу замінюєм в ньому адресу модуля розширення портів на свою в цій стрічці: byte addr[] = {0x20,0x41,0x42,0x0F,0x48,0x4E,0x59,0x49};).
Заливаєм ArduinoOWISP.hex в nano:
avrdude -P /dev/ttyUSB0 -c arduino -p m328p -U flash:w:ArduinoOWISP.hex
Тепер nano стала повноцінним програматором по 1-wire для pro-mini - можна не лише заливати і читати прошивку і EEPROM, а й змінювати ф'юзи. При цьому на pro-mini не потрібен ніякий бутлоадер, і можемо не боятися, що прошивка на віддаленій pro-mini зависне і ми втратим до неї доступ.
Заливаєм HCS301.hex в pro-mini:
avrdude -P /dev/ttyUSB0 -b 9600 -c avrisp -p m328p -U flash:w:HCS301.hex
Програма на pro-mini починає працювати, щось виводить в OWSerial і нам тепер треба побачити, що там виводиться. Для цього в nano заливаєм скетч-ретранслятор (перед компіляцією цього скетчу замінюєм в ньому адресу модуля розширення портів на свою в цій стрічці: byte addr[] = {0x20,0x41,0x42,0x0F,0x48,0x4E,0x59,0x49};).
Заливаєм OWSerialMaster.hex в nano:
avrdude -P /dev/ttyUSB0 -c arduino -p m328p -U flash:w:OWSerialMaster.hex
Цей скетч через модуль розширення портів забирає з буферу OWSerial дані і виводить в свій Serial (в зворотньому напрямку дані також будуть передаватися).
Дивимось, що в нас виводиться в Serial на nano:
minicom -D /dev/ttyUSB0 -b 9600
Listening RF
#12345 1B6A46A2 1
#12345 1B6A46A2 1 R
#12345 9F204069 2
#12345 9F204069 2 R
#12345 D6A5816C 1234 BatLow
#12345 D6A5816C 1234 BatLow R
На брелоку я послідовно натискав кнопки 1, 2 і 1+2. Приймач 433МГц підключений до піна 2 на pro-mini.
Ділюся досвідом, може кому знадобиться така ідея програмування для його задачі.
Виникла потреба віддалено керувати (додавати/видаляти) списком радіо-брелоків, які можуть відчиняти ворота. Керуванням воріт займається одна плата, а для подачі їй сигналу на відкривання використовувався китайський приймач 433МГц, який замикав своїм реле два контакти з цієї плати. Все це розташовано поряд з воротами в ящику. Додатково під землею/асфальтом вже давно був проведений кабель до пульту охорони, щоб кнопкою можна було також вручну відкрити ворота. Проблема в тому, що китайський приймач дозволяє лише додавати в свою память коди брелоків, для чого потрібно натиснути кнопку безпосередьо на його платі (а для цього потрібно до неї добратись).
Перш за все я перевірив, чи працюватиме 1-wire по двом проводам, які призначені для кнопки відкривання воріт на пульті охорони. 1-wire працює чудово за винятком періодів часу, коли працює мотор, який відкриває/закриває ворота (мабуть він в цей час створює завади через кабель живлення, який десь там під землею проходить поряд).
Спочатку була ідея віддалено модифікувати память китайського приймача (память в ньому 24LC16B з I2C інтерфейсом, формат збереження даних стає зрозумілим з першого разу після додавання нового брелоку і зчитування памяті). Модифікувати память можна було б по 1-wire за допомогою pro-mini, включеної за такою схемою:
До того ж за цією схемою можна віддалено оновлювати прошивку pro-mini, не відкриваючи ящик, в якому вона знаходиться.
Коли я почав придумувати протокол для додавання/видалення кодів брелоків по 1-wire, прийшла друга ідея.
По-перше відмовитися від китайського приймача, а написати його реалізацію на pro-mini.
По-друге не витрачати зусилля і час на придумування протоколу додавання/видалення кодів.
Ідея полягає в тому, щоб коди всіх брелоків помістити в програму (в PGM/EEPROM) і віддалено прошивати в pro-mini щоразу, коли потрібно якийсь брелок додати/видалити. Тобто редагуємо програму (додаємо/видаляємо код брелока в масиві), компілюємо і прошиваємо по 1-wire в pro-mini.
Отже, якщо стоїть задача розробки протоколу для віддаленого керування якоюсь базою даних на ардуіно і немає вимог до доступності до цієї ардуіни 100% часу, то можна не витрачати зусилля на розробку такого протоколу. Для цього можна щоразу зчитувати з віддаленої ардуіни її память, модифікувати і записувати назад.