Получение и считывание массива из serial

oleg.vresh
Offline
Зарегистрирован: 10.10.2019

Всем привет!

Есть две Ардуины. Одна работает как приемник, другая как передатчик. связанны по сериал. Передатчик отправляет массив на приемник. приемник получает массив, и в соответствии с полученным массивом, устанавливает значения на пины, так же записывает их  в  ЕЕПРОМ.

код передатчика (чисто для проверки приемника):

int sentArray3[] = {1, 1, 1, 1, 1};
void setup() 
{
Serial.begin(9600);
}
void loop()
{
  for (int i = 0; i < (sizeof(sentArray3) / sizeof(int)); i ++)
  {
    Serial.println(sentArray3[i]);
  }
  delay(5000);
}

код приемника:

#include <EEPROM.h>
int incomingValue;
int relayPins[] =   {8, 9, 10, 11, 12};
int statesArray[] = {0, 0,  0,  0,  0};
void setup() 
{
  //relay pins setup
  for (int i_Setup=0 ; i_Setup < (sizeof(relayPins) / sizeof(int)); i_Setup++)
  {
    pinMode(relayPins[i_Setup], OUTPUT);
    digitalWrite(relayPins[i_Setup], LOW);
  }
  
  Serial.begin(9600);
}
void loop()
{
  
//Restore pins states from EEPROM
  for (int i_EEPROM = 0; i_EEPROM < (sizeof(statesArray) / sizeof(int)); i_EEPROM ++)
  {
    statesArray[i_EEPROM] = EEPROM[i_EEPROM];
  }

//Reading array of pin state from serrial port
  for (int i_Read = 0; i_Read < (sizeof(statesArray) / sizeof(int)); i_Read ++)
  {
    if (Serial.available() > 0 )
    {
      incomingValue = Serial.parseInt();
      statesArray[i_Read] = incomingValue;
    }
  }
  
//Applying values of readed array items to relayPins
  for (int i_Write = 0; i_Write < (sizeof(statesArray) / sizeof(int)); i_Write ++)
  {
    if (statesArray[i_Write] == 0)
    {
      digitalWrite(relayPins[i_Write], LOW);
      EEPROM.update(i_Write, 0);
    }
    if (statesArray[i_Write] == 1)
    {
      digitalWrite(relayPins[i_Write], HIGH);
      EEPROM.update(i_Write, 1);
    }
  }
  // debug 
  
  //outputing statesArray
  Serial.println("statesArray");
  for (int j = 0; j < (sizeof(statesArray) / sizeof(int)); j++)
  {
    Serial.println(statesArray[j]);
  }
  
  //outputing EEPROM
  Serial.println("EEPROM");
  for (int j = 0; j < (sizeof(relayPins) / sizeof(int)); j++)
  {
    Serial.println(EEPROM[j]);
  }
}

Суть проблемы:

приемник получает массив, поджигает нужные пины, сохраняет состояния в ЕЕПРОМ, но не на долго.

через 1 цикл, нулевой элемент массива statesArray[0] становится нулем,даже если не должен. далее после получения нового массива снова на 1 проход принимает нужное значение,и снова через проход 0.

путем отключения модулей понял, что ошибка где-то в чтении, только где точно не могу разобраться.

sadman41
Offline
Зарегистрирован: 19.10.2016

println() заменить на write, parseInt() на read().

oleg.vresh
Offline
Зарегистрирован: 10.10.2019

простите, а зачем? println() тут только для отладки, а read() сделает statesArray[] ={10,49,13,10,49}

sadman41
Offline
Зарегистрирован: 19.10.2016

Уточняю: в передатчике println() заменить на write(), в приёмнике parseInt() на write. Это для скорости. А вообще - проблема в строке #26

b707
Offline
Зарегистрирован: 26.05.2017

oleg.vresh пишет:

простите, а зачем? println() тут только для отладки, а read() сделает statesArray[] ={10,49,13,10,49}

не хотите слушать советы - разбирайтесь сами.

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

oleg.vresh пишет:

простите, а зачем? println() тут только для отладки, а read() сделает statesArray[] ={10,49,13,10,49}

не хотите слушать советы - разбирайтесь сами.

Да не, вопрос в тему. Просто я отвлёкся и мысль не совсем до конца дописал.

Проблема-то классическая - читаются N байт без ожидания их прихода на сторону приёмника.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Что передаётся в конце строки (это написано в правом нижнем углу монитора порта, который Вы не привели)? Наверняка и \r, и \n. Сделайте, чтобы было что-то одно и всё нормализуется.

oleg.vresh
Offline
Зарегистрирован: 10.10.2019

Большое, человеческое СПАСИБО, Вам добрый человек. Заработало!

когда поменял в передатчике на write, и в приемнике на read... 

 -"читаются N байт без ожидания их прихода на сторону приёмника."

--подскажите пожалуйста, как реализовать ожидание?

oleg.vresh
Offline
Зарегистрирован: 10.10.2019

ЕвгенийП пишет:

Что передаётся в конце строки (это написано в правом нижнем углу монитора порта, который Вы не привели)? Наверняка и \r, и \n. Сделайте, чтобы было что-то одно и всё нормализуется.

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

oleg.vresh
Offline
Зарегистрирован: 10.10.2019

sadman41 пишет:

b707 пишет:

oleg.vresh пишет:

простите, а зачем? println() тут только для отладки, а read() сделает statesArray[] ={10,49,13,10,49}

не хотите слушать советы - разбирайтесь сами.

Да не, вопрос в тему. Просто я отвлёкся и мысль не совсем до конца дописал.

Проблема-то классическая - читаются N байт без ожидания их прихода на сторону приёмника.

 

Заработало! когда поменял в передатчике на write, и в приемнике на read... 

 

 -"читаются N байт без ожидания их прихода на сторону приёмника."

 

--подскажите пожалуйста, как реализовать ожидание?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Самое тупое ожидание можно реализовать при помощи while, но обычно в каждом конкретном случае можно применить более изящное, но, увы, не универсальное решение. Как - полностью определяется конкретными особенностями проекта.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

oleg.vresh пишет:

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

Понятно, но это тоже ничего не меняет. Значит, println отправляет \r\n. Замените на print и отправляйте только один символ-разделитель вручную. Иначе у Вас первый \r считается концом числа, а следующий \n концом следующего числа.

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

Понятно, но это тоже ничего не меняет. Значит, println отправляет \r\n. Замените на print и отправляйте только один символ-разделитель вручную. Иначе у Вас первый \r считается концом числа, а следующий \n концом следующего числа.

Тогда бы там через строчку был бы 0, полагаю. А тут только один раз.  

В этом коде грабли разложены почти по всей поверхности ))