Передать и принять Integer по Serial

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

27-ая строка второго кода (приёмника) - опять двадцать пять?!

А зачем так хитро-то? У Вас же чёрт ногу сломит. Вам чего нужно-то? массив передать? Так и передавайте его в лоб, делов-то. Я вчера Вам предлагал показать как, хотите, таки покажу :)

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Женя! Я запутался. Что нужно ему сделать? Что, откуда и куда перелать?

andrikll
Offline
Зарегистрирован: 04.08.2013

wdrakula Да уже переделывать не надо, это не работало как надо. А с Вашей помощью разобрался, переписал все заново и сразу заработало. Как обычно, не задал себе вопросы при написании кода которые задаю другим, а когда спрашивал уже начало понемногу доходить. пока все переписывал чтобы показать как не работает, заработало. (не без помощи форумчан)

ЕвгенийП С удовольствием увижу код который проще.....

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

Я так понял, что надо переслать массив с одного девайса на другой. Но вместо того, чтобы так и написать:

Serial.write(massiv, sizeof(massiv));

Человек зачем-то развёл бодягу на десятки строк со сдвигами какими-то :) Принять, оно, конечно, чуть сложнее, но тоже не через такие же Альпы, как там написано :)

andrikll
Offline
Зарегистрирован: 04.08.2013

Почитал я что передается байтами, яж не просто так это писал со сдвигами, в лоб я даже одно значение не мог передать int подумал что из-за особенностей передачи, а про свои ошибки (ктож их видит) не подумал.

Да и сайзоф не знаю.... прочитал...

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

andrikll пишет:

Как обычно, не задал себе вопросы при написании кода которые задаю другим, а когда спрашивал уже начало понемногу доходить.

( замечание не по делу) 

....удивительная порода людей. которая при любой крохотной проблеме первым делом несется на форум задавать вопросы....

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

andrikll
Offline
Зарегистрирован: 04.08.2013

b707

Так замечание к самому себе... могу наверно...

ЕвгенийП

Спасибо! понятно что это проще, но пока только сложнее получается.... За сим откланиваюс

 

 

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

Не понял, чем эта одна строчка сложнее Ваших 10-ти, ну ладно, Вам виднее. Когда созреете узать как это принимать, скажите :)

andrikll
Offline
Зарегистрирован: 04.08.2013

Я не созрел...если вам не сложно... я попытаюсь понять. Из прочитанного в описаниях ясно что она делает, не ясно как. Для начала как отправлять.

RX_Serial.write(data_tx_int, sizeof(data_tx_int)); 

no matching function for call to 'SoftwareSerial::write(int [6], unsigned int)'

Попробовал и с индексами (массива)

А еще скажите как вы с подсветкой синтаксиса вставляете текст? Из редактора, он там уже в цвете? У меня сайзоф не подсвечено в ИДЕ.

 

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Просто он не sizeoff а sizeof

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Вот пример для пересылки массива. Сделан так, как это НАДО делать.

Никаких обсуждений или замечаний не нужно.

НУЖНО распечатать на ватмане, 32 кеглем, повесить над кроватью и запоминать наизусть.

-----

Тут много чисто оформительских вещей, но сапиенти сат.

ПЕРЕДАЧА

/*
Это пример работает в паре с SerialIntArrayRx

написан для постановки точки в вопросах новичков о том, как передавать целые по сериалу

пример формирует массив целых двубайтных чисел размером, указанным в объявлении массива

далее программа заполняет его случайнвми положительными целыми , сама считает его длину и ЦРЦ
и всю эту кухню отправляет по софт-сериалу в формате
<data:xy>zzzzzz zzzCRC16</data>
где xy - количество байт в передаче, zzz... сами целые двубайтные, CRC16 - она сама и есть 
*/

#include <stdint.h>
#include <util/crc16.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

int Arr2test[32];  //можно выбрать размер от 1 до 99


void setup() {
  Serial.begin(57600);
  while (!Serial);

  mySerial.begin(19200);


}

void loop() 
{ 
  int len=sizeof(Arr2test);
  uint16_t  crc=0; 
  uint16_t d;
  for (int i = 0; i<(len/2)-1; i++) //заполняем массив случайными чисоами
    {
      d =  random(INT16_MAX);
      Arr2test[i] = d;
      crc=_crc16_update(crc, d&0xff); //..и одновременно считаем ЦРЦ
      crc=_crc16_update(crc, d>>8); 
    }
  Arr2test[len/2-1] = crc;  
  len = sizeof(Arr2test);
  
  Serial.print("Array complete CRC is: 0x");
  Serial.println(crc);
  Serial.print("Array length = ");
  Serial.println(len/sizeof(int));
  
  mySerial.print("<data:");
  mySerial.print(len);
  mySerial.print(">");
  mySerial.write ((byte *)Arr2test,len); //вот в этой строке массив целых собственно и передается
  mySerial.print("</data>");

delay(1000);  
}

ПРИЕМ

/*
Пример работает в паре с SerialIntArrayTx

Программа получает по софт-сериалу данные в формате
<data:xy>zzzzzzzzzzzzzzzzzCRC16</data>
где xy - байт в передаче, а zzz... собственно сами двубайтные целые числа подряд в формате "первый байт младший"

Считаем ЦРЦ библиотечной функцикй от 0

*/
#include <stdint.h>
#include <util/crc16.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(8, 9); // RX, TX

int Arr2test[100]; //максимально 100 штук, включая CRC

void setup() 
{
  Serial.begin(57600);
  while (!Serial);
  
  mySerial.begin(19200);
  mySerial.setTimeout(999);
}

void loop() 
{
  int len, i;
  uint16_t crc=0;
  bool noerr=true;
if (mySerial.available())
  {
    
    if (noerr = (noerr && mySerial.find("<data:")))
    {
      Serial.println("Found start tag");
      len = mySerial.parseInt();
      Serial.print("Ints to read: ");Serial.println(len/2);
      noerr = noerr && len < 200;
      noerr = noerr && mySerial.find(">");
      mySerial.readBytes((byte *)Arr2test,len); // вот в этой строке массив целых принимается
      noerr = noerr && mySerial.find("</data>");

      for(i=0; i < len -2; i++) crc = _crc16_update(crc, *((byte *)Arr2test + i));
      if (noerr && crc == Arr2test[len/2 - 1])
      {
        Serial.print ("Received ");
        Serial.print (len/2);
        Serial.print (" int Array. CRC - OK = ");
        Serial.println (crc);
      }
      else // это обработка ошибок. приучайтесь сразу закладывать ее в проект
      {
        Serial.print ("Syntax or CRC error!  ");
        Serial.print (noerr);
        Serial.print (" CRC recv/send");
        Serial.print(crc,16);
        Serial.print (" / ");
        Serial.print(Arr2test[len/2-1],16);
        Serial.println();
      }
    }
  }
  
}

 

andrikll
Offline
Зарегистрирован: 04.08.2013

Все супер, повешу и буду до "отскакивания от зубов" учить, только пока не понятно мне *. Я читал про указатели, понятно что это, но всю кенструкцию целиком я представить в голове не могу, как и синтаксис использования, поэтому штука класная, но можно я только строчку с 

mySerial.write ((byte *)Arr2test,len); 

заберу к себе в скетч и поучусь еще.....?

Это же можно без указателя использовать, обращаясь к самим данным массива?

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

andrikll пишет:

Я не созрел...если вам не сложно... я попытаюсь понять. Из прочитанного в описаниях ясно что она делает, не ясно как. Для начала как отправлять.

RX_Serial.write(data_tx_int, sizeof(data_tx_int)); 

no matching function for call to 'SoftwareSerial::write(int [6], unsigned int)'

Ну, поставьте (byte *) перед data_tx_int Получится

RX_Serial.write((byte *)data_tx_int, sizeof(data_tx_int));

делов-то.

andrikll
Offline
Зарегистрирован: 04.08.2013

Да ясно, не окажется потом, что где то нельзя что то ставить, потому что, что-нибудь перезатрется и это всем ясно кроме меня...(при следующем вопросе)  ? Так то я пользовался (нашел пример ) , передавал по радио и работало только в массиве с 4-мя переменными байт и никак иначе (конечно не исключены фор инт и;...).
В чем необходимость использования указателя?
Почему просто переменная не котируется?

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

andrikll пишет:

Почему просто переменная не котируется?

Потому, что разработчики Ардуино написали для класса потока функцию write с параметрами

write(<указательл на начало>, <количество байтов>)

а мы этой функцией пользуемся, уж какая есть.

andrikll
Offline
Зарегистрирован: 04.08.2013

Понятно....Догма, ну чтож, беру и пользуюсь как есть. Я любое могу разобрать на баиты? Флоат и лонг? Или только баит и интеджер?.... Попробую

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

в С, именно в нем, в С++ немного иначе, с КАЖДОЙ переменной связано ее ИМЯ,

например с long L будет связано имя &L, оно имеет тип "указатель на лонг", то есть (long *)

Как и с любым указателем, его можно преобразовать в указатель на что угодно и обратитьсяк любому байту из него:

((byte*) &L)[0] - младший байт, и  ((byte *) &L)[3] -  старший, соответственно.

Таким образом передаем long по сериалу:

Serial.write((byte*)&L,4); где 4 написано вместо sizeof(long)

или int: Serial.write((byte*)i, 2); если i  целое, 2 - это, конечно, sizeof(int).

Общая схема такая:

Serial.write((byte*) УКАЗАТЕЛЬ_НА_ДАННЫЕ, КОЛИЧЕСТВО_БАЙТ_В_ПЕРЕДАЧЕ);

колчество удобно посчитать чеерез sizeof(), а указавтель - это массив (он в С сразу указатель, всегда), или имя в смысле &ПЕРЕМЕННАЯ, для иных типов.

Запутал или прояснил? ;)

andrikll
Offline
Зарегистрирован: 04.08.2013

Не запутали, очень познавательно, спасибо! Не скажу что уровень полного осознания, надо пробовать и применять, буду.... Помню пытался передать без понимания, просто подбирал такое выражение которое не выдавало ошибок и без понимания добился какого то результата.. Очень неприятно использовать что то, когда не знаешь что оно может выкинуть в следущий раз. 

 А описание где либо и суховато и описания аргументов (в примерах) всегда не хватает.

компилируется без ошибок...

int var, mass[6];
void setup() {
Serial.begin(9600);
}

void loop() {
Serial.write((byte *)&var, sizeof(var));
Serial.write((byte *)mass, sizeof(mass));
}
А это 
mySerial.readBytes((byte *)Arr2test,len);

соберет массив в адреса ячеек которые будут выделены под массив., так же как и рабирались? Неясно как она собирает, если массив уже передан и весь в буфере? Судя по вашему примеру нет, потому что там 100 элементов по 2 байта, а буфер 128 байт. Как он индексы ячеек перебирает и т.д.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Что значит передан и весь в буфере? readBytes это просто функция которая заменяет примерно такой код

while(count_read < len)
{
  a = Serial.read();
  *buffer++ = a;
  count_read++;
}

Это слегка упращено, там еще таймаут учавствует. Поэтому вы просто читаете приходящий байт кладете его в память и сдвигаете указатель в памяти на следующий байт и так по кругу пока есть что читать. Не шлется сразу 200 байт, байты уходят по одному и на другой стороне тут же читаются, так что если нормально программа написана буфера в 128 байт хватит за глаза.

andrikll
Offline
Зарегистрирован: 04.08.2013

Penni Спасибо, что так подробно, не разобрал функцию приема, поэтому спрашивал (не видел как приемник ждет начала пакета).. сейчас разобрал. Но Ваше пояснение актуально. Со всем теперь разобрался...

 

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

andrikll пишет:

Со всем теперь разобрался...

Уверены? Там в примере сильно упрощено. Попробуйте-ка сами принять :)

andrikll
Offline
Зарегистрирован: 04.08.2013

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

В передатчике непонятно как это работает, _crc16_update не объявлялось (ошибок не выдало). Ну допустим 42 строчка наверно суммирует элементы массива смещенные на байт. а 41 я в затруднении.  

41       crc=_crc16_update(crc, d&0xff); //..и одновременно считаем ЦРЦ
42       crc=_crc16_update(crc, d>>8);
 

Потом эта строчка, котороую я попробовал у себя и заработало, здесь дает ошибку

   mySerial.readBytes((byte *)Arr2test, len); 

говорит что из байта в чар оно "не пройдет"

И в приемнике тоже самое, непонятно что и как формирует эта строка (ясно что контрольную сумму, но...)

   crc = _crc16_update(crc, *((byte *)Arr2test + i));

спустя время увидел что срс16 задается библиотекой...полез читать что там и как

Попробовал, readBytes пишет не умеет конвертить байт в чар.

invalid conversion from 'byte*' to 'char*'

andrikll
Offline
Зарегистрирован: 04.08.2013

Вот так работает.

Передача 

#include <SoftwareSerial.h>

SoftwareSerial RX_Serial(10, 11); // RX, TX
int data_tx_int[]={1508,128,129,1,130,131};
int tx_count;

void setup()  {  
  Serial.begin(9600); 
  RX_Serial.begin(1200);
              }
              
  void Write_Serial () {
    if(tx_count==0) {RX_Serial.print("."); }    
    RX_Serial.write((byte *)data_tx_int, sizeof(data_tx_int)); 
    tx_count++;
                     }

 void loop() {   
    if(tx_count<12) Write_Serial(); else tx_count++;
    if(tx_count>1000) tx_count=0;
           }

Прием

#include <SoftwareSerial.h>

SoftwareSerial RX_Serial(10, 11); // RX, TX

int dat_vol;
int data_rx_int[6];
int len=6;

void setup()  {  
  Serial.begin(9600); 
  RX_Serial.begin(1200);
               }

 void Read_Serial() { if (RX_Serial.available()) { 
  if(RX_Serial.find(".")){  RX_Serial.readBytes((char *)data_rx_int, len*2); } } 
               }

  void Print_Serial() {
    for(int i=0; i<len; i++) {Serial.print(data_rx_int[i]); Serial.print(" ");}
    Serial.println();  
                 }
 
  void loop() {   
    Read_Serial (); 
   if(millis()%100==0) Print_Serial(); 
              }

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

andrikll пишет:

invalid conversion from 'byte*' to 'char*'

первое:

в некоторых версиях среды Arduino IDE не включено разрешения преобразования типов.

Я поискал полчаса - не нашел таких, но помню, что были. Проверил самую свежую 1.8.5 (Линух 64) - тоже нормально реагирует на преобразование типов.

Может в "мире Виндоус" какая-то разница? - можно у Евгения спросить, у меня нет компьютеров с MS Windows, только виртуалки со старой XP. Что сделатьс ИДЕ в Виндоус, чтобы на преобразование типов не ругалась - это к Евгению.

Если у тебя странная/старая версия и ты не можешь поменять ее на нормальную,то просто замени везде byte на char это вообще ничего не изменит.

Можно еще добавить опцию -fpermissive компилятору, но, опасаюсь, что это для тебя непосильная задача. ;) -Без обид?

byte это unsigned char,  в контексте Ардуинки,  от замены на char ничто в коде не пострадает. ;)

=================================

и второе: Зачем ты сейчас полез разбираться с CRC? Это как-то влияет на твою задачу? Мозги перегреются и закипят. Делай все поэтапно.

Сперва разберись с передачей данных, а проверку целостности, как то CRC, оставь на потом. Пока ты еще путаешься даже в передаче параметров функции. Чего стоила фантазия о копировании массива  в некий волшебный буфер, это было супер!

И читай одновременно учебник по С. Ссылку у Евгения попроси, у него удобная есть, или найди сам в гугле "Керниган и Ритчи".

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

О! Пока я писал трактат, ты и сам справился! Малацца!

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

почитай вот эту статью

и пиши программы правильно.

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

Я использую стиль GNU, ИДЕ сразу предлагает стиль Кернигана-Ритчи. Неважно какой - лишьбы читалось.

andrikll
Offline
Зарегистрирован: 04.08.2013

Ок, спасибо! Да, туда лезть нет смысла там ассемблер оказался. Интересно как работает контрольная сумма, но думаю это пока не нужно, все отлично работает и втом что я написал все понятно...

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

А отступы это я люблю...читаю сижу

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

andrikll пишет:

Вот так работает.

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

Это работает из серии:

1.       Ура, заработало!

2.       Ой, что-то иногда нет-нет, да глючит

3.       Глючит редко и случайно, наверное помехи, «мужики, как с помехами бороться?»

4.       Блин, всё равно нет-нет, да глючит «мужики, как вочдог присобачить?»

5.       О, теперь потянет

Т.е. у Вас изначально заложены ошибки, приводящие к глюкам, а потом Вы будете лечить их костылями.

Посмотрите на строки 14-16 приёмника.

1.       Вы проверили, что в порту ЧТО-ТО есть и сразу в наглую читаете весь массив. А что будет, если он пришёл не целиком? Вы налетите на таймаую и будете ждать. Во время ожидания программа заблокирована, никакие кнопки не опрашиваются, экраны не обновляются и т.п. Если не дождётесь, то слетите по таймауту (а Вы этого не проверяете).
2.       И что ещё за поиск точки? А если там затешется число 46, оно ведь тоже точка.
3.       len*2 – формально типа правильно, но идейно – совершенно неверно. Вам же говорили, пишите sizeof(data_rx_int).

andrikll
Offline
Зарегистрирован: 04.08.2013

Я не сомневаюсь в том что Вам понятно больше, но я этого не вижу без Вас... Так что нет смысла говорить "я не понял".

1 Ваш вопрос, это мой вопрос из #68 сообщения. Я не знал на него ответ и пока еще не знаю... понимаю что что то возможно, но что и из за чего чтобы это предотвратить, конечно не знаю. (Точнее так, я видел что это есть в примере дракулы, но пока осознано не могу это применить, поэтому сделал без этого)

Пересмотрел пример дракулы и от "обрыва" передачи там только тайм аут 999 (по умолчанию же он 2000?) Как это кардинально меняет ситуацию?

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

3. Ясно...

Да же не знаю что сказать, замечания Ваши правомерны, но это не вопрос 10 минут (обучение) с моими 1.5 строки в неделю. 

Теперь опишу как с моей точки зрения... Написал я побайтную отправку, ее можно вызывать раз в n циклов и так же принимать. ничего не виснет, можно сделать маленький тймаут. Вы пишете , да ктож так пишет.. надо все и сразу.. Ну ок посмотрел Ваши примеры, попробовал, работает как то в моем сознании. Теперь, да ктож так делает, теперь оно и зависнуть может.... Какой то снежный ком... 

В программировании наверно нет совершенного чего то, я понимаю что мое вобще и близко не стояло, но если не умеешь на формуле-1 наверно стоит на жигулях покататься я думаю...(писать так как научился маленько, закрепить, может и ошибки половить... моя не писатель так то в форумы, просто набрел на интересную тему, решил спросить....)

 

Учиться всегда надо, я не могу так быстро.... надеюсь на Ваше понимание... (хотя и так все тут полезного понаписали, спасибо!)

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

andrikll пишет:
Написал я побайтную отправку, ее можно вызывать раз в n циклов и так же принимать. ничего не виснет, можно сделать маленький тймаут. Вы пишете , да ктож так пишет.. надо все и сразу.. Ну ок посмотрел Ваши примеры, попробовал, работает как то в моем сознании. Теперь, да ктож так делает, теперь оно и зависнуть может.... Какой то снежный ком... 

Так ото ж! :)))))))))))

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

1.У меня и нет никакой защиты. Евгений "щадит мое самолюбие" ;). Он хочет научить тебя неблокирующему чтению, а я считаю, что пока рано. Это разные педагогические методики. Да и сам я стану писать неблокирующий код, только если мне это реально нужно.

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

Единственно можно добавить проверку вида:

if (len != mySerial.readBytes(data,len)) <какая-то обработка ошибки>;

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

andrikll пишет:

Учиться всегда надо, я не могу так быстро.... надеюсь на Ваше понимание... (хотя и так все тут полезного понаписали, спасибо!)

Понимаешь, мне вот 48 лет, через 2 недели будет... если  доживу.;)

Программирую я всю жизнь на всех языках. Иногда мне кажется, что первым словом было не "Дай!", как у нормальных детей, а "GOTO". ;)

Поэтому мне реально тяжело представить себе, что просто,а что не просто для понимания.

У многих "стариков" так.

andrikll
Offline
Зарегистрирован: 04.08.2013

Это я как раз таки понимаю... и рад что все равно пишите в новичковые темы....

Я так понимаю что 

if (len != mySerial.readBytes((byte *)Arr2test, sizeof(Arr2test))) return;

Я например могу поставить сразу после

mySerial.readBytes((byte *)Arr2test,sizeof(Arr2test));

?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

не угадал... думай дальше.

andrikll
Offline
Зарегистрирован: 04.08.2013

wdrakula  Для начала хотелось бы определиться с тем кодом что вы сбросили.

Как я понимаю в Вашем коде приема

mySerial.readBytes((byte *)Arr2test,len); 
      noerr = noerr && mySerial.find("</data>");

В этих двух строчках, сначала считывается весь массив и пока не считается не переходит на строчку поиска окончания массива. Если так, то неясно как вмешаться в этот процесс, если не так, то непонятно цикл crc 200 раз пересчитывается?

for(i=0; i < len -2; i++) crc = _crc16_update(crc, *((byte *)Arr2test + i));

 

 

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

andrikll пишет:

В этих двух строчках, сначала считывается весь массив и пока не считается не переходит на строчку поиска окончания массива. Если так, то неясно как вмешаться в этот процесс

Зачем вмешиваться?

andrikll пишет:
непонятно цикл crc 200 раз пересчитывается?

Не "пересчитывается", а считается по всем 200 значениям. Вы вообще понимаете, как устроена CRC?

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

andrikll пишет:

wdrakula  Для начала хотелось бы определиться с тем кодом что вы сбросили.

Как я понимаю в Вашем коде приема

mySerial.readBytes((byte *)Arr2test,len); 
      noerr = noerr && mySerial.find("</data>");

В этих двух строчках, сначала считывается весь массив и пока не считается не переходит на строчку поиска окончания массива. Если так, то неясно как вмешаться в этот процесс, если не так, то непонятно цикл crc 200 раз пересчитывается?

for(i=0; i < len -2; i++) crc = _crc16_update(crc, *((byte *)Arr2test + i));

1. Да нет!  проверку можно вставить просто заменив строчку с чтением без проверки, на строчку с проверкой.

вместо

mySerial.readBytes((byte *)Arr2test,len); 

писать

noerr = noerr && (len == mySerial.readBytes((byte *)Arr2test,len) ); 

поиск завершающего тэга написан для красоты, в целях алгоритма смысла не имеет никакого. Такие вещи пишут на автомате, для возможной расширяемости...в отдаленной перспективе ;).

2. а почему 200 раз??????????? от 2 до len-2 , то есть на 2 байта меньше длины сообщения. Именно потому,что в  последних двух байтах мы и держим ЦРЦ.

Не стоит пока забиватьсебе голову ЦРЦ. Если трудно понимать- замените просто на сумму всех байт сообщения.

 

andrikll
Offline
Зарегистрирован: 04.08.2013

Понятно, 200 раз.. это как "если не так"....(массив 100 по байтам 200).

В этих двух строчках, сначала считывается весь массив и пока не считается не переходит на строчку поиска окончания массива. Если так, то неясно как вмешаться в этот процесс, если не так, то непонятно цикл crc 200 раз пересчитывается?

Плюс не привык к записи и расчету булеан, хотя нравится и начинаю привыкать. Не знал что вобще можно без иф что то сразу и расчитать и присвоить.

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

andrikll пишет:

Понятно, 200 раз.. это как "если не так"....(массив 100 по байтам 200).

я уставать начинаю. 100 - "с запасом". чтобы не учить еще "маллоку", а len мы СЧИТЫВАЕМ, в моем коде - в строке 39.

andrikll
Offline
Зарегистрирован: 04.08.2013

Невнимательно прочел, инициализацию не запомнил, в Вашем коде Arr2test[32] и len=64.

sana555
Offline
Зарегистрирован: 11.05.2018

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

Что значит "не зашло". Должно заходить, куда оно нахрен денется-то?

Ну, если хотите, я могу сделать Вам пример с двумя ардуинами в протеусе. Надо?

Я хочу..) Пытаюсь наладить связь между двумя ардуино уно в протеусе, не получается. Соединил 10 с 11, 11 с 10 пинами. Нужно еще землю между ними объединить, но на платах в протеусе пина с GND нет...

Передача:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600); 
}

void loop() { // run over and over
  mySerial.println(123); 
}

Прием:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600); 
}


unsigned long timing7;
void loop() { // run over and over
   if (millis() - timing7 > 2000){          
     timing7 = millis();            
     if (mySerial.available()>0) {        
       Serial.println(mySerial.read());         
     }
  }                                    
}

 

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

И не надо, земля и без Вас объединена.

sana555
Offline
Зарегистрирован: 11.05.2018

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

И не надо, земля и без Вас объединена.

Так и подумал, получается в коде накосячил?

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

Ну, в коде-то конечно накосячено, Вы шлетё постоянно, а принимаете раз в две секунды. И куда девается всё, что передали?

sana555
Offline
Зарегистрирован: 11.05.2018

Убал в приемнике millis(), теперь принимает постоянно, все равно в мониторе порта нет никаких данных.

sana555
Offline
Зарегистрирован: 11.05.2018

Получилось завести на реальном железе, данные передаются..)

Передача: 

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <SoftwareSerial.h>

SoftwareSerial mySerial(13, 15); // // виртуальные контакты RX и TX

#define BLYNK_PRINT Serial

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "**************";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "*****";
char pass[] = "***************";

/////////////////////////////////////////////////////////////////////  
void setup()
{
  // Debug console
  Serial.begin(57600); // Запускаем последовательную передачу данных и ждем открытия порта:  
  mySerial.begin(19200);
  Blynk.begin(auth, ssid, pass);  
}

/////////////////////////////////////////////////////////////////////  
unsigned long timing7;    
void loop()
{
  Blynk.run();
  
  if (millis() - timing7 > 2000){     
    Termistor();  // вычисляем сопротивление термистора в Омах.   
    timing7 = millis();     
    //отправляем в последовательный порт mySerial 
    mySerial.print("<tempD:");
    mySerial.print(123);  
    mySerial.print("</tempD>"); 
    mySerial.print(" ");  
    mySerial.print("<tempP:");
    mySerial.print(68);  
    mySerial.print("</tempP>");                                    
  } 
}

Прием

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // // виртуальные контакты RX и TX

/////////////////////////////////////////////////////////////////////  
void setup()
{
  // Debug console
  Serial.begin(57600); // Запускаем последовательную передачу данных и ждем открытия порта:
  while (!Serial);
  mySerial.begin(19200); 
  mySerial.setTimeout(1999); 
}

/////////////////////////////////////////////////////////////////////  
unsigned long timing7;    
void loop() {  
  int len;
  if (mySerial.available()>0) {    
    if (mySerial.find("<tempD:")) {
      len = mySerial.parseInt();
      if (len > 0) {
        Serial.print(len);
        Serial.print(" ");
      } 
    } 
    if (mySerial.find("<tempP:")) {
      len = mySerial.parseInt();
      if (len > 0) {
        Serial.println(len);
      } 
    }   
  }      
}   

Но только не всегда корректные:

[SPOILER]123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
123 68
 
3  
3  3  
3  
3  3  3  
3  
3  
3  3  3  
3  
3  3  
3  3  
123 68
123 68
123 68
123 68
123 68
123 68
 3  
3  
3  
3  3  3  
3  
3  3  
3  3  
3  
3  3  
3  
3  
3  
123 68
123 68
123 68
123 68
 3  3  
3  
3  3  
3  3  
3  
3  3  
3  
3  
3  
3  
3  
3  3  
123 68
123 68
3  
3  3  
3  3  
3  
3  3  
3  
3  
3  
3  
3  
3  3  
3  
3  
123 68
123 68
123 68
123 68
123 68
123 68[/SPOILER]

 

 

sana555
Offline
Зарегистрирован: 11.05.2018

Опять в коде ошибка, или это последствия использования программного serial?

sana555
Offline
Зарегистрирован: 11.05.2018

Добавил всего лишь один пробел и ситуация значительно изменилась в лучшую сторону, те 3 стали выходить очень редко, но все равно выходят нет нет...):

Serial.println(" ");

Прием

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // // виртуальные контакты RX и TX

/////////////////////////////////////////////////////////////////////  
void setup()
{
  // Debug console
  Serial.begin(57600); // Запускаем последовательную передачу данных и ждем открытия порта:
  while (!Serial);
  mySerial.begin(19200); 
  mySerial.setTimeout(1999); 
}

/////////////////////////////////////////////////////////////////////  
unsigned long timing7;    
void loop() {  
  int len;
  if (mySerial.available()>0) {    
    if (mySerial.find("<tempD:")) {
      len = mySerial.parseInt();
      if (len > 0) {
        Serial.print(len);
        Serial.print(" ");
      } 
    } 
    if (mySerial.find("<tempP:")) {
      len = mySerial.parseInt();
      if (len > 0) {
        Serial.println(len);
        Serial.println(" ");
      } 
    }   
  }      
}   
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

попробуйте скорость уменьшить. У Вас великовата.

sana555
Offline
Зарегистрирован: 11.05.2018

Здесь?:  Serial.begin(57600);