Проблемы с подсветкой светодиодов при получении Arduino с учетом массива символов при отправке Arduino в Tinkercad
Суть проблемы в том, что я пытаюсь получить Arduino с макетной платой, которая имеет 5 кнопок и 4 светодиода, каждый светодиод связан с кнопкой, а пятая кнопка «отправляет» свет, который был включен, с помощью массив символов на принимающий Arduino, в этом Arduino этот алгоритм Arduino имеет макетную плату с 4 светодиодами одного цвета, и с помощью массива символов я пытаюсь переключить те же светодиоды, которые были включены в первом Arduino, моя проблема в том, что когда я отправьте массив символов и получите его во втором Arduino и попробуйте запустить функцию, которая проходит через массив, и найдите, какие точки в массиве символов отличаются от 0, и включите светодиод, он никогда не включает светодиоды, я знаю, что логика правильно, но я не понимаю, почему это не работает.
Это проект, над которым я работаю в tinkercad, и я также свяжу проект, если вы хотите запустить его там, я предполагаю, что проблема связана с tinkercad, а не с кодом, хотя я могу ужасно ошибаться.
Это скетч отправителя
#include <SoftwareSerial.h>
#define rxPin 9
#define txPin 8
// Инициализируем контакты 4 светодиодов отправителя и получателя
const int ledRed = 13;
const int ledBlue = 12;
const int ledGreen = 11;
const int ledWhite = 10;
// iniciamos los pins de los 5 botones
const int pushbuttonRed = 7;
const int pushbuttonBlue = 6;
const int pushbuttonGreen = 5;
const int pushbuttonWhite = 4;
const int pushbuttonEnviar = 3;
// Объявить состояние 4 светодиодов отправителя и получателя
int ledStateRed = 0;
int ledStateBlue = 0;
int ledStateGreen = 0;
int ledStateWhite = 0;
char c;
char leds[7] = {'H','0','0','0','0','F','\0'};
//Строка cadena_final = "";
SoftwareSerial receiver = SoftwareSerial(rxPin, txPin);
void setup() {
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
Serial.begin(9600);
receiver.begin(9600);
pinMode(ledRed, OUTPUT);
pinMode(ledBlue, OUTPUT);
pinMode(ledGreen, OUTPUT);
pinMode(ledWhite, OUTPUT);
pinMode(pushbuttonRed, INPUT);
pinMode(pushbuttonBlue, INPUT);
pinMode(pushbuttonGreen, INPUT);
pinMode(pushbuttonWhite, INPUT);
pinMode(pushbuttonEnviar, INPUT);
}
void loop() {
// Ботон Рохо
if(digitalRead(pushbuttonRed) == 1) {
digitalWrite(ledRed, HIGH);
ledStateRed += 1;
leds[1] = '1';
if(ledStateRed % 2 == 0){
digitalWrite(ledRed, LOW);
leds[1] = '0';
ledStateRed = 0;
}
delay(100);
}
// Ботон Азул
if(digitalRead(pushbuttonBlue) == 1) {
digitalWrite(ledBlue, HIGH);
ledStateBlue += 1;
leds[2] = '1';
if(ledStateBlue % 2 == 0){
digitalWrite(ledBlue, LOW);
ledStateBlue = 0;
leds[2] = '0';
}
delay(100);
}
// Ботон-Верде
if(digitalRead(pushbuttonGreen) == 1) {
digitalWrite(ledGreen, HIGH);
ledStateGreen += 1;
leds[3] = '1';
if(ledStateGreen % 2 == 0){
digitalWrite(ledGreen, LOW);
ledStateGreen = 0;
leds[3] = '0';
}
delay(100);
}
// Ботон Бланко
if(digitalRead(pushbuttonWhite) == 1) {
digitalWrite(ledWhite, HIGH);
ledStateWhite += 1;
leds[4] = '1';
if(ledStateWhite % 2 == 0){
digitalWrite(ledWhite, LOW);
ledStateWhite = 0;
leds[4] = '0';
}
delay(100);
}
// Ботон Энвиар
if(digitalRead(pushbuttonEnviar) == 1) {
// Reinicio los leds de sender para enviar otro mensaje
ledStateWhite = 0;
ledStateGreen = 0;
ledStateBlue = 0;
ledStateRed = 0;
digitalWrite(ledWhite, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledBlue, LOW);
digitalWrite(ledGreen, LOW);
delay(100);
Serial.write(leds,7);
leds[1] = '0';
leds[2] = '0';
leds[3] = '0';
leds[4] = '0';
}
}
void printArray(char A[]){
int i = 0;
for(i=0;i<6;i++){
Serial.print(A[i]);
}
}
Это скетч приемника
#include <SoftwareSerial.h>
#define rxPin 9
#define txPin 8
char leds2[7] = {'\0'};
// Iniciamos los pins de los 4 светодиода
const int Red = 4;
const int Blue = 5;
const int Green = 6;
const int White = 7;
// Creamos el boton que limpia pantalla
const int buttonClear = 10;
char c;
String recData;
SoftwareSerial receiver = SoftwareSerial(rxPin, txPin);
void setup() {
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
receiver.begin(9600);
pinMode(Red, OUTPUT);
pinMode(Blue, OUTPUT);
pinMode(Green, OUTPUT);
pinMode(White, OUTPUT);
Serial.begin(9600);
}
void loop() {
int i=0;
if (receiver.available()) {
delay(100); //позволяет получить все отправленные серийные номера вместе
while(receiver.available() && i<6) {
leds2[i] = receiver.read(); // начинается с i=0
delay(100);
i++;
}
leds2[i]='\0';
// цифровая запись (красный, ВЫСОКИЙ);
}
if(i>0) {
lightLeds(leds2);
}
}
void lightLeds(char A[]){
int i;
for(i=0;i<6;i++){
if(A[1]=='1' || A[1]==1) digitalWrite(Red, HIGH);
if(A[2]=='1' || A[2]==1) digitalWrite(Blue, HIGH);
if(A[3]=='1' || A[3]==1) digitalWrite(Green, HIGH);
if(A[4]=='1' || A[4]==1) digitalWrite(White, HIGH);
}
}
void printArray(char A[]){
int i = 0;
for(i;i<6;i++){
Serial.print(A[i]);
}
}
@LuiGiovanni, 👍1
1 ответ
Лучший ответ:
Ваша "рабочая логика" совершенно нелогична:
В отправителе вы определяете массив символов:
char leds[6] = {'H','0','0','0','0','F'};
что должно быть
char leds[7] = {'H','0','0','0','0','F','\0'}; // завершаем массив
Здесь каждый "0" представляет светодиод, как это видно из подпрограммы Boton Enviar
.
Вместо того, чтобы назначать состояние каждой позиции 0/1, чтобы светодиоды [2] = '1' были, например, синим светодиодом, вы записываете в него число (пример для синего):
if(digitalRead(pushbuttonBlue) == 1) {
digitalWrite(ledBlue, HIGH);
ledStateBlue += 1;
leds[2] = '5'; // Здесь должно быть leds[2] = '1';
if(ledStateBlue % 2 == 0){
digitalWrite(ledBlue, LOW);
ledStateBlue = 0;
leds[2] = '0';
так что если синий и и вы отправляете (если используете терминатор)
leds[] = {'H','5','0','0','0','F'.'\0'};
На стороне получателя происходит следующее:
while(receiver.available() && i<6) {
leds2[i++] = receiver.read(); // начинается с i=1
delay(100);
}
leds2[i++]='\0';
digitalWrite(Red,HIGH);
}
if(i>0) {
lightLeds(leds2);
чтобы ваш светодиод2 выглядел как
{XX,'H','5','0','0','0','F'} //XX - это неопределенный мусор, может быть '\0', поэтому массив заканчивается здесь
Решение определяет массив следующим образом:
char leds2[7] ={'\0'};
.....
while(receiver.available() && i<6) {
leds2[i] = receiver.read(); // начинается с i=0
delay(100);
i++;
}
leds2[i]='\0';
// digitalWrite(Red,HIGH); // Встроенный светодиод USE не один из используемых в качестве «конечного маркера»
}
if(i>0) {
lightLeds(leds2)
Легкая логика должна работать с пробелом, которым является значение, а не значение:
void lightLeds(char A[]){
int i;
for(i=0;i<6;i++){
if(A[2]=='1' || A[2]==1) digitalWrite(Blue, HIGH);
if(A[2]=='0' || A[2]==0) digitalWrite(Blue, LOW);
....
}
}
Чтобы разделить сочетание различных логик, поместите обе программы в редактор (например, notepad++) рядом и найдите различия в логике. В программах есть более одной ошибки, исправьте их, как было предложено, и все заработает (подробности читайте в комментариях к моему коду).
ОБНОВЛЕНО
У ОП все еще были проблемы с его кодом. Я взял пример и позволил ему работать на оборудовании на основе двух UNO, это сработало, но SoftwareSerial очень плохой. Никаких проблем с оборудованием с AltSoftSerial.h. В TinkerCAD никаких шансов, в тот момент, когда я переключился на HW-Serial, он работал как шарм, поэтому вот усовершенствованный код для SENDER:
// Переменные времени
unsigned long startTime = 0;
unsigned long intervalTime = 1000; // отправляем раз в секунду
// Инициализируем контакты 4 светодиодов отправителя и получателя
const int ledRed = 13;
const int ledBlue = 12;
const int ledGreen = 11;
const int ledWhite = 10;
// iniciamos los pins de los 5 botones
const int pushbuttonRed = 7;
const int pushbuttonBlue = 6;
const int pushbuttonGreen = 5;
const int pushbuttonWhite = 4;
const int pushbuttonEnviar = 3;
// Объявить состояние 4 светодиодов отправителя и получателя
int ledStateRed = 0;
int ledStateBlue = 0;
int ledStateGreen = 0;
int ledStateWhite = 0;
char c;
char leds[7] = {'H', '0', '0', '0', '0', 'F', '\0'};
//Строка cadena_final = "";
SoftwareSerial sender = SoftwareSerial(rxPin, txPin);
void setup() {
pinMode(ledRed, OUTPUT);
pinMode(ledBlue, OUTPUT);
pinMode(ledGreen, OUTPUT);
pinMode(ledWhite, OUTPUT);
pinMode(pushbuttonRed, INPUT);
pinMode(pushbuttonBlue, INPUT);
pinMode(pushbuttonGreen, INPUT);
pinMode(pushbuttonWhite, INPUT);
pinMode(pushbuttonEnviar, INPUT);
sender.begin(19200);
DEBUG_INTERFACE.begin(9600);
DEBUG_INTERFACE.println("DEBUG ON");
}
void loop() {
// Ботон Рохо
if (digitalRead(pushbuttonRed) == 1) {
digitalWrite(ledRed, HIGH);
ledStateRed += 1;
leds[1] = '1';
if (ledStateRed % 2 == 0) {
digitalWrite(ledRed, LOW);
leds[1] = '0';
ledStateRed = 0;
}
}
// Ботон Азул
if (digitalRead(pushbuttonBlue) == 1) {
digitalWrite(ledBlue, HIGH);
ledStateBlue += 1;
leds[2] = '1';
if (ledStateBlue % 2 == 0) {
digitalWrite(ledBlue, LOW);
ledStateBlue = 0;
leds[2] = '0';
}
}
// Ботон-Верде
if (digitalRead(pushbuttonGreen) == 1) {
digitalWrite(ledGreen, HIGH);
ledStateGreen += 1;
leds[3] = '1';
if (ledStateGreen % 2 == 0) {
digitalWrite(ledGreen, LOW);
ledStateGreen = 0;
leds[3] = '0';
}
}
// Ботон Бланко
if (digitalRead(pushbuttonWhite) == 1) {
digitalWrite(ledWhite, HIGH);
ledStateWhite += 1;
leds[4] = '1';
if (ledStateWhite % 2 == 0) {
digitalWrite(ledWhite, LOW);
ledStateWhite = 0;
leds[4] = '0';
}
}
// Ботон Энвиар
if (digitalRead(pushbuttonEnviar) == 1) switchAll();
if (millis() - startTime > intervalTime) {
DEBUG_INTERFACE.println(leds);
sender.println(leds);
startTime = millis();
}
}
void switchAll() {
// Reinicio los leds de sender para enviar otro mensaje
ledStateWhite = 0;
ledStateGreen = 0;
ledStateBlue = 0;
ledStateRed = 0;
digitalWrite(ledWhite, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledBlue, LOW);
digitalWrite(ledGreen, LOW);
DEBUG_INTERFACE.println(leds);
leds[1] = '0';
leds[2] = '0';
leds[3] = '0';
leds[4] = '0';
}
и код для ПОЛУЧАТЕЛЯ:
// Iniciamos los pins de los 4 светодиода
const int Red = 4;
const int Blue = 5;
const int Green = 6;
const int White = 7;
// Creamos el boton que limpia pantalla
const int buttonClear = 10;
char rc;
const int maxChar = 6;
static byte charCount = 0;
char leds2[7] = {'\0'};
bool newData = false;
#define DEBUG_INTERFACE Serial
#define receiver Serial
void setup() {
receiver.begin(9600);
pinMode(Red, OUTPUT);
pinMode(Blue, OUTPUT);
pinMode(Green, OUTPUT);
pinMode(White, OUTPUT);
DEBUG_INTERFACE.begin(9600);
DEBUG_INTERFACE.println("DEBUG ON");
}
void loop() {
receiveStartEndMarkers();
if (newData) {
DEBUG_INTERFACE.print(" LED Array received: ");
DEBUG_INTERFACE.println(leds2);
lightLeds(leds2);
newData = false;
}
}
void lightLeds(char A[]) {
for (int i = 0; i < 6; i++) {
if (A[1] == '1' || A[1] == 1) digitalWrite(Red, HIGH);
if (A[2] == '1' || A[2] == 1) digitalWrite(Blue, HIGH);
if (A[3] == '1' || A[3] == 1) digitalWrite(Green, HIGH);
if (A[4] == '1' || A[4] == 1) digitalWrite(White, HIGH);
if (A[1] == '0' || A[1] == 0) digitalWrite(Red, LOW);
if (A[2] == '0' || A[2] == 0) digitalWrite(Blue, LOW);
if (A[3] == '0' || A[3] == 0) digitalWrite(Green, LOW);
if (A[4] == '0' || A[4] == 0) digitalWrite(White, LOW);
}
DEBUG_INTERFACE.print(A); DEBUG_INTERFACE.println(" Leds switched");
}
void receiveStartEndMarkers() {
static boolean recvInProgress = false;
char startMarker = 'H';
char endMarker = 'F';
if (receiver.available() > 0) {
rc = receiver.read();
//DEBUG_INTERFACE.print(rc);
if (recvInProgress) {
if (rc != endMarker) {
leds2[charCount] = rc;
charCount++;
if (charCount > maxChar) {
charCount = maxChar;
}
}
else {
leds2[charCount] = rc;
charCount++;
leds2[charCount] = '\0'; // завершаем строку
recvInProgress = false;
charCount = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
leds2[charCount] = rc;
charCount++;
}
}
}
Рабочий код выглядит следующим образом: замените HW-Serial 0(RX), 1(TX) на 1(TX), 0(RX):
В результате НЕ ИСПОЛЬЗУЙТЕ SoftwareSerial.h в TinkerCAD - в данный момент он не работает, используйте серийный номер HW для примеров связи, иначе вы сойдете с ума, если рабочий код вдруг выведет мусор. При использовании реального оборудования используйте AltSoftSerial (полнодуплексный режим). Если вы планируете использовать свой дизайн с реальным оборудованием, используйте резисторы для светодиодов (найдите светодиод калькулятора резисторов), поскольку для светодиодов разных цветов требуются разные значения резисторов.
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Я добавил все предложенные изменения, но проблема осталась, индикаторы на втором ардуино не загораются. Также я не могу найти продолжение в комментариях, как вы предлагаете в конце вашего поста., @LuiGiovanni
Там код отредактировал, @LuiGiovanni
Конечно, вот ссылка на tinkercad: https://www.tinkercad.com/things/37CXjQkn6Bi-copy-of-4-buttons-4-leds/editel?sharecode=dSsvqDLMEfnYp7htfceDF2-BnIh1-h0FegRC5zt1KdQ, @LuiGiovanni
Загадка решена, см. мое редактирование выше, пример по вашей ссылке теперь полностью работает - получайте удовольствие, и если все в порядке, отметьте как решенное Спасибо., @Codebreaker007
Извините, похоже, что и получатель, и отправитель имеют один и тот же код., @LuiGiovanni
Взломщик кодов, у меня не работает. Светодиоды на втором Arduino не загораются, а второй Arduino никогда не получает массив светодиодов или, по крайней мере, сообщение никогда не отображается., @LuiGiovanni
Исправлен код (ошибка c&p). Конечно, вы должны использовать HW Serial, поэтому подключите 0 (RX), 1 (TX) от одного Uno к 1 (TX), 0 (RX) к другому и удалите последовательные кабели sw, которые я тестировал в течение часа, он работает на 100%., @Codebreaker007
Да, это работает. Большое спасибо., @LuiGiovanni