Пришла недавно Arduino Pro mini, появилась мысль использовать её в своем проекте, как дополнение к основной Arduino Uno. Идея заключается в том, чтобы перенести часть работы, в частности с дисплеем, с Uno на Mini, освободив тем самым кучу памяти на Uno. Но вот вопрос, как обеспечить связь между этими двумя устройствами? Пример: на Uno стоит ИК-приемник, пришел какой-то код в итоге действие выполнила и Uno и Mini, изменив изображение на LCD. Связь проводная, т.к. планирую их разместить на одной плате. Куда копать? С Mini уже поигрался, сумел помигать светодиодом, прошивал через Uno с извлеченным чипом (atmega328), но дальше никак идей. При этом нужен минимальный отклик, так чтобы выполненное действие на Uno, практически сразу отобразилось и на дисплее, подключенный к Mini. Спасибо.
Ну конечно можно! Все проще чем вы думаете. Для этого у Вас есть RX и TX. Покажу схему в один конец, тоесть 1- передает, другой принимает. Думаю с кодом разберетесь, если нет могу помочь.
Привожу пример схемы С двустороним общением. Принцып у кода будет тот-же, только функци больше. Скетч настряпаю и выложу.
Ну чето типо этого: Это от куда... Код (C++): #include <VirtualWire.h> void setup() { Serial.begin(9600); vw_set_tx_pin(10); vw_set_rx_pin(9); vw_set_ptt_inverted(true); vw_setup(9000); vw_rx_start(); } void loop() { if (digitalRead(12)==HIGH) { read_send(); } } void read_send(){ const char *msg = "hello"; uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; String aa; vw_wait_rx(); if (vw_get_message(buf, &buflen)) { int i; for (i = 0; i < buflen; i++) { aa=aa+(char)buf[i]; } Serial.print(aa); Serial.println(""); if (aa=="A2") { const char *msg = "A2"; digitalWrite(13, true); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); digitalWrite(13, false); } } } Это куда: Код (C++): #include <VirtualWire.h> void setup() { Serial.begin(9600); vw_set_tx_pin(12); vw_set_ptt_inverted(true); vw_setup(9000); vw_rx_start(); pinMode(9, OUTPUT); } void loop() { digitalWrite(9, HIGH); sendd("A1");//сообщение для контроллера digitalWrite(9, LOW); } void sendd(const char *msg){ uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; String aa; vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); if (vw_wait_rx_max(30))//30 { if (vw_get_message(buf, &buflen)) { digitalWrite(13, true); int i; for (i = 0; i < buflen; i++) { aa=aa+(char)buf[i]; } Serial.println("Ответ от: "+aa); digitalWrite(13, false); } else Serial.println("GetMes"); } }
Дальше САМ, ГИК Если код недоработан, не удивляйся! Стряпал, на скорую) Да и еще по кускам А у меня такой вопрос: Я знаю что таким макаром можно подключить не одну дуину, как потребитель. Вопрос: Сколько их можно подключить? Столько сколько портов на хватит?
Ух, огромное спасибо! Постараюсь разобраться. Получается у Arduino-мастера должно быть 3 свободных пина. Пины могут быть любыми, не обязательно 9, 11 и 12? Интересно, к библиотеке написан недостаток - использование таймеров. Не знаете какие таймеры там используются? Не будет ли мешать работе ИК-приемника?
Я этот код собрал из частей. С этим никогда не работал, но по идее не должен мешать, вы же сигналы от арды к арде не по воздуху передаете...
По подключению хотел уточнить - 9 порт Uno к 12 на Mini, а 12 порт Uno к 9 на Mini; и 11 порт Uno к 10 Mini через резистор (1 - 10 кОм). Я прав?
У меня две ардуины нано общаются по RX и TX. Первая является " Главным компьютером " Собирает информацию о температуре и влажности, имеет часы реального времени, и будильник. Выводит значения на маленький дисплейчик. Вторая , спрашивая у первой "Сколько времени" выводит время и только его, на дисплей по больше. Изначально задумка была соединить контроллеры одним проводом: главный выдает - другой принимает. Но столкнулся с проблемой, что второй контроллер не знал где начало у передачи и цифры плясали как могли. Тогда было решено соединить двумя проводами по которым : Ведомый контроллер раз в секунду "говорит" - "выдай мне" а ведущий не чего не говорит(только молча слушает слушает звуки космоса) , а выдает шесть переменных и прекращает передачу.
Если соединить TX первого с RX второго, то все будет передаваться. Либо вы неправильно настроили, либо забыли земли контроллеров соединить.
Что же вы такое написали, что вам памяти не хватило? Можно повесить на SPI карточку SD - это проще и дешевле (стоимость карты + несколько резисторов), чем городить второй контроллер.
Эта проблема решается синхромаркером, который идет в начале каждого цикла передачи. Другой вариант - использование контрольной суммы. Можно использовать оба метода одновременно.
Хм, боюсь SD карточку подключить не куда, все занято. Код есть в теме. Из этого, как минимум 30% занимает именно текстовый LCD экран, а в будущем я планирую разжиться TFT 3.95" для которого уж точно потребуется второй МК, ну как я полагаю. Так библиотека VirtualWire по сути и есть RX-TX, TX-RX, только ещё с защелкой, как у SPI. Не могу разобраться с данной библиотекой. Проверьте меня: Код (C++): // Код для Uno #include <VirtualWire.h> void setup() { Serial.begin(9600); vw_set_tx_pin(12); vw_set_ptt_inverted(true); vw_setup(9000); vw_rx_start(); pinMode(9, OUTPUT); } void loop() { digitalWrite(9, HIGH); sendd("A1");//сообщение для контроллера digitalWrite(9, LOW); } void sendd(const char *msg) { uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; String aa; vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); if (vw_wait_rx_max(30))//30 { if (vw_get_message(buf, &buflen)) { digitalWrite(13, true); int i; for (i = 0; i < buflen; i++) { aa = aa + (char)buf[i]; } Serial.println("Ответ от: " + aa); digitalWrite(13, false); } else Serial.println("GetMes"); } } Код (C++): // Код для Mini #include <VirtualWire.h> void setup() { Serial.begin(9600); vw_set_tx_pin(10); vw_set_rx_pin(9); vw_set_ptt_inverted(true); vw_setup(9000); vw_rx_start(); } void loop() { if (digitalRead(12) == HIGH) { read_send(); } } void read_send() { const char *msg = "hello"; uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; String aa; vw_wait_rx(); if (vw_get_message(buf, &buflen)) { int i; for (i = 0; i < buflen; i++) { aa = aa + (char)buf; } Serial.print(aa); Serial.println(""); if (aa == "A1") { const char *msg = "A1"; digitalWrite(13, true); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); digitalWrite(13, false); } } } По подключению - 9 порт Uno к 12 на Mini, а 12 порт Uno к 9 на Mini; и 11 порт Uno к 10 Mini через резистор (1 - 10 кОм). Правильно? Принцип работы должен быть такой, как я понял: Uno притягивает 9 пин к питанию, т.е. на 12 для Mini - начинается передача. Дальше Uno отправляет сообщение "А1". Mini начинает читать сообщения, если это "А1", то мигает светодиодом (13) и посылает ответ. Uno его принимает и печатает нам в порт. Но этого не происходит. Вообще тишина, ничего не происходит.
Ляпнул не разобравшись, сори. Второй день колдую над этой библиотекой, что-то получилось. Упросил коды до нельзя. Код (C++): // Uno #include <VirtualWire.h> uint8_t buf_out1[10]; //исходящее сообщение 1 контроллера int sr; void setup() { //настройка virtualWire vw_set_tx_pin(7);//пин передачи vw_set_rx_pin(8);//пин приема vw_set_ptt_inverted(true); vw_setup(9000);//скорость передачи данных /*———————————————————————*/ Serial.begin(9600); /*———————————————————————*/ } void loop() { if (Serial.available()) //Ожидаем опроса сериал { sr = Serial.read(); delay(40); if (sr == 53) //если через сериал-консоль послали текст равный 5 { Serial.println("5"); buf_out1[0] = 0xf1; //формируем буфер для отправки vw_send(buf_out1, sizeof(buf_out1)); //отправляем } } } Код (C++): // Mini #include <VirtualWire.h> uint8_t buf_in[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; void setup() { //настройка vitrualwire vw_set_tx_pin(7); vw_set_rx_pin(8); vw_set_ptt_inverted(true); vw_setup(9000); vw_rx_start(); //включаем прием сообщение через virtualwire } void loop() { if (vw_get_message(buf_in, &buflen)) //если пришло сообщение { digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); int value_1;//сообщение с главного контроллера value_1 = buf_in[1]; switch (value_1) { case 0xf1: //команда с главного контроллера digitalWrite(13, HIGH); break; } } } Добился того, что светодиод на Mini сигнализирует, когда что-то приходит к ней, но теперь ломаю голову, как заставить её распознавать что именно приходит, пока безрезультатно, что я делаю не так? По идее, все же просто, формируем буфер и отправляем 0xf1, при поступлении 0xf1 на mini светодиод должен загораться, но этого не происходит.
Получилось !!! Да, Вы Megakoteyka, правы, насчет буфера, конечно я отправлял первый байт, а читал второй, в котором ничего не было. Ух. Чудеса Сейчас попробую прикрутить обратную посылку отчета от slave (mini) к master (master).