Проблемы с подсветкой светодиодов при получении 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]);
    }
}


, 👍1


1 ответ


Лучший ответ:

2

Ваша "рабочая логика" совершенно нелогична:

В отправителе вы определяете массив символов:

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

,

Я добавил все предложенные изменения, но проблема осталась, индикаторы на втором ардуино не загораются. Также я не могу найти продолжение в комментариях, как вы предлагаете в конце вашего поста., @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