Serial.print VS Serial.write проблема решена, непонимание осталось

rapidshe
Offline
Зарегистрирован: 31.12.2015

Добрый день! подскажите пожалуйста. проблему то решил, но понять не могу(гуглил уже).

две ардуины, общаются между собой. вторая при этом болтает с ГСМ модулем, поэтому(мало "полноценных" сериалов у уны) и долго решалась проблема, т.к. не видно было что приходит к ней из первой ардуины.

суть пока простая.

через монитор порта в первую ардуину отправляю "1", она шлет это во вторую и на той должен инвертироваться светодиод. но этого не происходило.

в итоге оказалось что при пересыле "1" с первой ардуины на вторую посредством .print() на вторую приходил код символа "1" т.е. 49

но при этом вторая ардуина при приеме смски пересылала данные на первую посредством того же .print() и числа и строки приходили нормально

 

в итоге в первой ардуине заменил .print() на .write() и данные стали приходить нормально на вторую.

Но не могу понять почему одна при помощи .print() отправляет(ну или принимает) нормально, а вторая нет.

на всякий случай скетчи

первой:


#include <SoftwareSerial.h>

SoftwareSerial monport(7, 8); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  monport.begin(9600);
  monport.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  Serial.begin(9600);
  Serial.println("Hello, world?");
}

void loop() { // run over and over
  if (Serial.available()) {
    monport.write(Serial.read());
  }
  if (monport.available()) {
    Serial.write(monport.read());
  }
}

второй:

// библиотека для работы с GPRS устройством
#include <GPRS_Shield_Arduino.h>
 
// библиотека для эмуляции Serial-порта
// она нужна для работы библиотеки GPRS_Shield_Arduino
#include <SoftwareSerial.h>
//SoftwareSerial ard2(3, 4);  
// длина сообщения
#define MESSAGE_LENGTH 160
char message[MESSAGE_LENGTH]; // текст сообщения
char phone[16];// номер, с которого пришло сообщение
char datetime[24];// дата отправки сообщения
int messageIndex = 0;

char ch;
String val;

// создаём объект класса GPRS. По умолчанию скорость общения с ним 9600 бод
// с помощью него будем давать команды GPRS шилду
GPRS gprs(9,12,7,8); //PowerPin,StatusPin,RX,TX


 

 
void setup()
{
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  digitalWrite(14,LOW);
  digitalWrite(15,LOW);
  gprs.powerUpDown();
  Serial.begin(9600);
   while (!gprs.init()) {
    // если связи нет, ждём 1 секунду
    // и выводим сообщение об ошибке;
    // процесс повторяется в цикле,
    // пока не появится ответ от GPRS-устройства
    delay(1000);
   Serial.print("Init error\r\n");
  }
  // выводим сообщение об удачной инициализации GPRS Shield
  Serial.println("GPRS init success");
 
  Serial.println("Please send SMS message to me!");
}
 
void loop()
{
  // если пришло новое сообщение
  if (gprs.ifSMSNow()) {
    // читаем его
    gprs.readSMS(message, phone, datetime);
    // выводим номер, с которого пришло смс
    Serial.print("From number: ");
    Serial.println(phone);
    // выводим дату, когда пришло смс
    Serial.print("Datetime: ");
    Serial.println(datetime);
    // выводим текст сообщения
    Serial.print("Recieved Message: ");
    Serial.println(message);
    }

  if (Serial.available()) {  //обработка Serial данных
    while (Serial.available()) 
         {  //сохраняем строку в переменную val
         ch = Serial.read();
         val += char(ch);
         delay(10);
         }
         Serial.println(val);
    if (val.indexOf("1") > -1) 
         {
         digitalWrite(14,!digitalRead(14));
         }
         if (val.indexOf("2") > -1) 
         {
         digitalWrite(15,!digitalRead(15));
         }

   val="";  //очищаем
  }
}

ПС: а выяснил путем подключения одной ардуины к двум мониторам(через SoftwareSerial и хардовый)

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

Думаю, что через монитор порта Вы изначально отправляете не число "1", а символ "1" с кодом 49.

Serial.read() возврвщает целое число, т.е. в Вашем случае число 49. А опратором print оно преобразуется в строку из двух символов "49".

попытайиесь в первой явно укуазать тип:

monport.print((char)Serial.read());

ivanchekalov
Offline
Зарегистрирован: 25.08.2016
byte a = 1;
char b[10] = {a};
void loop{
Serial.print(b[0]};
}

Я эту проблему так решил

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

Т.е. путем 1000% перерасхода памяти, не говоря о лишних операциях?

 

ivanchekalov
Offline
Зарегистрирован: 25.08.2016

Каждому по потребностям 

rapidshe
Offline
Зарегистрирован: 31.12.2015

Спасибо, проблема выскакивала на этапе начального пристреливания.  как раз таки изза того что не был определен тип перевылаемых данный. и использовал write.

А когда в итоге я начала предварительно из кусков String строк склеивать в одну и потом её пересылать - всё приходило четко. и как оказалось "String" нельзя отправлять посредствам write

ivanchekalov
Offline
Зарегистрирован: 25.08.2016

А как ты строку пересылаешь?

rapidshe
Offline
Зарегистрирован: 31.12.2015

нууууу как например в монитор порта) только в данном случае по Serial у меня общаются ардуины, а по monport я подключаю монитор порта

void smssend(String phone) { //процедура отправки СМС
buf=F("sms");
buf+=F("#");
buf+=phone;
buf+=F("#");
buf+=sms;
sms="";
monport.println("buf:"+ buf);
Serial.println(buf); 
buf="";
}

 

 

ivanchekalov
Offline
Зарегистрирован: 25.08.2016

А на второй ардуине строку разбираешь?

buf объявлена как String?

rapidshe
Offline
Зарегистрирован: 31.12.2015
char ch;
String buf="";
String val[]={"","","","",""};




  if (Serial.available()) {  //обработка Serial данных
     while (Serial.available()) 
           {  //сохраняем строку в переменную val
           ch = Serial.read();
           buf += char(ch);
           delay(10);
           }
 //    Serial.println(buf);
     rasshifrovka();
     buf="";  //очищаем
     }  





void rasshifrovka() {
digitalWrite(14,!digitalRead(14));
val[0]="";
val[1]="";
val[2]="";
int n=0;
for(int i = 0; i <= buf.length() -1; i++) {
    if(buf.charAt(i)!= '#') {
      val[n]+= buf.charAt(i);
      }
    if((buf.charAt(i)== '#') && n<=1) {
      n+=1;
      }
    }
    buf="";
}

# у меня маячек разделения строк