запись символов в массив

xoyushka
Offline
Зарегистрирован: 02.10.2017

требуется решить задачу не знаю как.

в порт записывается строка: Led_2_6666 (_ ) - пробел)
как прочитать строку по символьно и записать значения в массивы
если led_2 то mLed2[]={6,6,6,6}
если led_3 то mLed3[]={6,6,6,6}

 

 

что то недоконца работает

String BUFFER[8];
String inString = "";
char inChar;

void setup()
{
Serial.begin(115200);
}

void loop()
{

if(Serial.available()) // Слушаем порт
{
inChar = Serial.read(); // Читаем символ
inString = inString+inChar; // Переводим Char в String, набираем нужное кол-во символов

if(inString.length() == 1) // Поймали1 символа
{
BUFFER[0] = inString;

inString = ""; // Обнуляем строку

Serial.println(BUFFER[0]);

}}}

 

 
 

 

 

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

xoyushka пишет:

требуется решить задачу не знаю как.

в порт записывается строка: Led_2_6666 (_ ) - пробел)
как прочитать строку по символьно и записать значения в массивы
если led_2 то mLed2[]={6,6,6,6}
если led_3 то mLed3[]={6,6,6,6}

 

что то недоконца работает

Так до начала тоже нихрена не работает.

Пришла буковка "L" (самая первая). Вы радостно кричите "поймали 1 символ". Запихиваете его в BUFFER[0]и обнуляете строку. Потом пришла буковка "e". Вы снова радостно кричите "поймали 1 символ". Запихиваете его в BUFFER[0]и обнуляете строку.

Каков смысл этого действия? Для чего Вы его написали?

MaksVV
Offline
Зарегистрирован: 06.08.2015

учусь программитровать, поэтому практикуюсь на задачках из форума. Вот скетч



//загружай скетч, смотри в сериал мониторе как работет 

int mLed2[4] = {1,2,3,4}; //массивы лучше делать int в твоем случае
int mLed3[4] = {0,0,0,0}; //массивы лучше делать int в твоем случае

char inchar = '9';
String Rx = "Led_2_6666 (_)"; // эту строку ты получаешь в порту

void setup() {
 Serial.begin(9600);
 Serial.print(Rx); Serial.println("     //Эту строку ты получил из порта"); // полученная строка
Serial.println(""); Serial.print ("Такие массивы были сначала:");  Serial.println("");
 for  (int i=0; i<4; i++) {Serial.print(mLed2[i]); Serial.print("  ");} Serial.println("");  // распечатаем твои массивы 
 for  (int i=0; i<4; i++) {Serial.print(mLed3[i]); Serial.print("  ");} Serial.println("");  // распечатаем твои массивы 
 
 
 if ( Rx[4]=='2') for (int i=0; i<4;i++) mLed2[i]=Rx[i+6]-48;  //проверяем номер диода в 4-ом символе строки Rx и  записываем 4 символа (начиная с нулевого) в наш массив из строки RX (начиная с 6-го)
 if ( Rx[4]=='3') for (int i=0; i<4;i++) mLed3[i]=Rx[i+6]-48;  //проверяем номер диода в 4-ом символе строки Rx и  записываем 4 символа (начиная с нулевого) в наш массив из строки RX (начиная с 6-го)
// чтобы перевести из символьной переменной в int нужно отнять 48 

Serial.println("");
Serial.print ("такие массивы стали после парсинга строки1:"); Serial.println("");
for  (int i=0; i<4; i++) {Serial.print(mLed2[i]); Serial.print("  ");} Serial.println("");  // распечатаем твои массивы 
for  (int i=0; i<4; i++) {Serial.print(mLed3[i]); Serial.print("  ");} Serial.println("");  // распечатаем твои массивы 

Serial.println("");
//Теперь поменяем в полученной строке на Led3 посмотрим как работает
delay (1000);
String Rx = "Led_3_7485 (_)"; // эту строку ты получаешь в порту

 Serial.print(Rx); Serial.println("       //теперь такую строку ты получил из порта"); // полученная строка
 
 

if ( Rx[4]=='2') for (int i=0; i<4;i++) mLed2[i]= Rx[i+6]-48;  //проверяем номер диода в 4-ом символе строки Rx и  записываем 4 символа (начиная с нулевого) в наш массив из строки RX (начиная с 6-го)
if ( Rx[4]=='3') for (int i=0; i<4;i++) mLed3[i]= Rx[i+6]-48;  //проверяем номер диода в 4-ом символе строки Rx и  записываем 4 символа (начиная с нулевого) в наш массив из строки RX (начиная с 6-го)
// чтобы перевести из символьной переменной в int нужно отнять 48 

Serial.println(""); Serial.print ("такие массивы стали после парсинга строки2:");  Serial.println("");
for  (int i=0; i<4; i++) {Serial.print(mLed2[i]); Serial.print("  ");} Serial.println("");  // распечатаем твои массивы 
for  (int i=0; i<4; i++) {Serial.print(mLed3[i]); Serial.print("  ");} Serial.println("");  // распечатаем твои массивы 
}
void loop() {}

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

по сути тебе надо только 

int mLed2[4] = {1,2,3,4}; 
int mLed3[4] = {0,0,0,0}; 

String Rx = "Led_2_6666 (_)"; // эту строку ты получаешь в порту

void setup() {
 
  if ( Rx[4]=='2') for (int i=0; i<4;i++) mLed2[i]=Rx[i+6]-48;  
  if ( Rx[4]=='3') for (int i=0; i<4;i++) mLed3[i]=Rx[i+6]-48; 
}

void loop() {}

 

fogary
Offline
Зарегистрирован: 05.03.2016

xoyushka пишет:


if(Serial.available()) // Слушаем порт
{
inChar = Serial.read(); // Читаем символ
inString = inString+inChar; // Переводим Char в String, набираем нужное кол-во символов
...
 

Может так:

if (Serial.available()){
  inString = Serial.readString();
 ...

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

Serial.readString();   вроде как долго ждёт. может так стандартно: 


int mLed2[4] = {1,2,3,4}; 
int mLed3[4] = {0,0,0,0}; 

String currStr = "";
 
void setup() { Serial.begin(9600);}
  
void loop(){
   
    if (Serial.available())    {
        
    char inChar = Serial.read();    
    if ('\r' == inChar) {          //  если дождались возврата коретки, парсим 
       
  if (currStr[4]=='2') for (int i=0; i<4;i++) mLed2[i]=currStr[i+6]-48;  
  if (currStr[4]=='3') for (int i=0; i<4;i++) mLed3[i]=currStr[i+6]-48;         
           
          currStr = "";   } 
    
    else if ('\n' != inChar) currStr += String(inChar);  //добавляем в строку символы, пока не дождёмся перевода строки
    
    
                               }
}



 

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

MaksVV пишет:

Serial.readString();   вроде как долго ждёт.

 

Serial.readString() ничего не ждет. он читает то что есть в сериале в данный момент. Это надо учитывать в коде, а то многие ошибочно полагают, что Serial.readString() ждет символы перевода строки

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

b707 пишет:

Serial.readString() ничего не ждет. он читает то что есть в сериале в данный момент. 

Ну, таймаут-то вроде ей можно назначить, так что может и подождать немножко. Однако, она действительно не ждёт перевода строки и никакого другого симвлоа. Просто вычитывает то что есть.

Если надо ждать перевода строки или любого другого терминального символа, то лучше использовать readStringUntil(). Эта будет ждать терминального символа и вылетит когда либо дождётся, либо таймаут истечет.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Покажите пример аналогичный моему с readString, если не сложно. А то не пойму как его использовать. Только надо без задержек.

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

Ну, я пока не понимаю чего Вы просите. Вам говорят как раз о возможности дождаться терминального символа, а Вы "без задержек". А если не пришёл ещё конец строки, тогда чего делать?

MaksVV
Offline
Зарегистрирован: 06.08.2015

fogary пишет:

xoyushka пишет:


if(Serial.available()) // Слушаем порт
{
inChar = Serial.read(); // Читаем символ
inString = inString+inChar; // Переводим Char в String, набираем нужное кол-во символов
...
 

Может так:

if (Serial.available()){
  inString = Serial.readString();
 ...

 

вот человек предложил вместо Serial.Read применить Serial.readString. я это имел ввиду. Чем тут лучше будет Serial.readString? В примере, предложенным мной, символ будет "ожидаться", не тормозя программу. А как будет вести себя Serial.readString, дожидаясь необходимый символ? 

MaksVV
Offline
Зарегистрирован: 06.08.2015

b707 пишет:
Serial.readString() ничего не ждет. он читает то что есть в сериале в данный момент. 

вот что я нашел в описании. "Функция readString() считывает символы из потока, объединяя их в строку. Функция прекращает свою работу в случае таймаута (см. setTimeout())."

 открываем про setTimeout() там говорится "Функция setTimeout() устанавливает максимальное время ожидания потока данных (значение по умолчанию - 1000 миллисекунд). "

Т.е. будет ждать 1 сек даже если данных нет?

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

Блин, ну поставьте Вы как я Вам писал readStringUntil - Там же всё просто. Пришёл терминальный символ - всё ничего больше не ждём. не пришёл - ждём пока придёт. Вам всё равно конца строки ждать, так акая Вам нафиг разница?

MaksVV
Offline
Зарегистрирован: 06.08.2015

да мне не куда ставить, я просто тут мимо проходил, но хочу понять суть. Может Вы меня не правильно поняли, или я сам себя не понял. Я Вам толкую, что хочется научиться делать такие конструкции, чтоб программа не задерживалась (в данном случае чтение из буфера), ведь ещё может быть что-то другое в программе, которое не терпит задержки. пример из сообщения #5 будет нормально работать? если да, то хотелось бы увидеть что-то подобное но с readStringUntil или Serial.readString. Я всё это пишу с целью образования, чтобы программировать, а не кодить. Не пойму зачем использовать функции с таймаутами, когда чащеприменяемый Serial.read и так нормально сработает. 

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

MaksVV, попытайтесь внятно сформулировать: по какому критерию программа, читающая строку, может понять, что строка прочитана полностью?

Serial.read работает нормально (если им уметь пользоваться), но читает один байт, а не строку, поэтому поставленный вопрос остается открытым.

MaksVV
Offline
Зарегистрирован: 06.08.2015

пробел например или перевод строки или перевод каретки. Ну пусть Serial.read читает один байт, за несколько проходов будем ростить строку, пока не увидим критерий конца строки.

Мне было непонятно почему ТСу , который пытался с помощью Serial.read записать строку, предложили другие функции с таймаутами. чем они лучше? 

MaksVV
Offline
Зарегистрирован: 06.08.2015

Блин, неужели я так не умею мысли выражать. Чтоб, наконец, все поняли о чем я. вот вам два скетча загрузите, смотрите как мигает светодиод, когда отправляем на ардуино из монитора любые символы да побольше (кроме перевода каретки, кто не знает в мониторе ставим "нет конца строки")

первый 


int mLed2[4] = {1,2,3,4}; 
int mLed3[4] = {0,0,0,0}; 

String currStr = "";
 
unsigned long prev=0;
void setup() { Serial.begin(9600);
pinMode (13, OUTPUT);
digitalWrite (13, LOW);
}
  
void loop(){
   if (millis()-prev>100){digitalWrite(13, !digitalRead(13)); prev = millis();}
   
    if (Serial.available())    {
        
    char inChar = Serial.read();    
    if ('\r' == inChar) {          //  если дождались возврата коретки, парсим 
       
  if (currStr[4]=='2') for (int i=0; i<4;i++) mLed2[i]=currStr[i+6]-48;  
  if (currStr[4]=='3') for (int i=0; i<4;i++) mLed3[i]=currStr[i+6]-48;         
           
          currStr = "";   } 
    
    else if ('\n' != inChar) currStr += String(inChar);  //добавляем в строку символы, пока не дождёмся перевода строки
    
    
                               }
}



второй 


int mLed2[4] = {1,2,3,4}; 
int mLed3[4] = {0,0,0,0}; 

String currStr = "";
 
unsigned long prev=0;
void setup() { Serial.begin(9600);
pinMode (13, OUTPUT);
digitalWrite (13, LOW);
}
  
void loop(){
   if (millis()-prev>100){digitalWrite(13, !digitalRead(13)); prev = millis();}
   
    if (Serial.available())    {
       currStr = Serial.readStringUntil('\r');
 
   
  
       
 // if (currStr[4]=='2') for (int i=0; i<4;i++) mLed2[i]=currStr[i+6]-48;  
 // if (currStr[4]=='3') for (int i=0; i<4;i++) mLed3[i]=currStr[i+6]-48;         
           
          
    
   
    
    
                               }
}



 

nik182
Offline
Зарегистрирован: 04.05.2015

Что их загружать? И так понятно как они работают. Парсить строку надо только поглубже, а то символы разные бывают.
А с советами - если надо что то делать только по приходу строки проще стандартный парсер взять. С таймаутом и блокировкой. Если ещё что то делать во время ожидания строки - свой писать. Выбираешь сам, по задаче.

fogary
Offline
Зарегистрирован: 05.03.2016

Формат принимаемой строки всегда такого типа: "Led_2_6666 (_)"?

xoyushka
Offline
Зарегистрирован: 02.10.2017

Всем спасибоб задачу почти решил.

проблема осталась в том, что получаем строку из порта  string A =123456

и как эту строку записать в int led[]={1,2,3,4,5,6}

fogary
Offline
Зарегистрирован: 05.03.2016
int led[6];
String A = "123456";

for (int i = 0; i < 5; i++){
  led[i] = A[i] - '0';
}

 

xoyushka
Offline
Зарегистрирован: 02.10.2017

'0';  что это ?

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

http://www.industrialnets.ru/files/misc/ascii.pdf

Найдите в таблице, графа Char: 0 и 6, Теперь из значений в графе Dec вычтите первое из второго. Что получится?

xoyushka
Offline
Зарегистрирован: 02.10.2017

спасибо

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

b707 пишет:

Serial.readString() ничего не ждет. он читает то что есть в сериале в данный момент. 

Ну, таймаут-то вроде ей можно назначить, так что может и подождать немножко. Однако, она действительно не ждёт перевода строки и никакого другого симвлоа. Просто вычитывает то что есть.

Если надо ждать перевода строки или любого другого терминального символа, то лучше использовать readStringUntil(). Эта будет ждать терминального символа и вылетит когда либо дождётся, либо таймаут истечет.

А если надо принять строку символов и сохранить в char mystring[50] есть ограничение на длину строки для сериального порта, я о буфере в 16 байт или строка примется полностью, если укладывается в эти 50 байт?