Software Serial communication

Hi guys

I need to communicate 2 Arduinos nano and one of them receives a data from the usb serial(an integer value). I need to transmit this value to another Arduino. I tried to establish the communication between them, but nothing has worked out so far. Below you can find the codes:

Sender:

SoftwareSerial incomeData(8,9); //rx,tx

String dataPy;
int inPin = 2;
int i;
int dataIn;
volatile unsigned long timeout[4];
volatile int idx = 0;
volatile unsigned long actTime;

void setup() {

pinMode(inPin,INPUT); // set pinD2 up to input
DDRB = 1 << DDB0; // set pinD8 up to output
Serial.begin(115200);
incomeData.begin(9600);
attachInterrupt(digitalPinToInterrupt(inPin),peakID,RISING); // declarying the interrupt to be triggered

}

void loop() {

if(Serial.available()>0){ //Serial communication
dataPy = Serial.readString(); // read the string inside the buffer
dataIn = dataPy.toInt(); // convert income string to int
incomeData.print(dataIn);
}

actTime = millis(); // actTime stores the amount of time since the program started

for(i=0; i<4; i=i+1){
if(actTime - timeout == dataIn){
_ timeout*=0; //guarantee that the pulse is generated just one time*_
* PORTB = 1 << PB0; // HIGH*
* delayMicroseconds(50); // pulse width*
* PORTB = 0 << PB0; // LOW*
* delayMicroseconds(50);*
Receiver:
SoftwareSerial incomeData(10,11); //rx,tx
//String dataPy;
//char c;
int inPin = 2;
int i;
int dataIn;
volatile unsigned long timeout[4];
volatile int idx = 0;
volatile unsigned long actTime;
void setup() {

pinMode(inPin,INPUT); // set pinD2 up to input
DDRB = 1 << DDB0; // set pinD8 up to output
//Serial.begin(115200);
incomeData.begin(9600);
attachInterrupt(digitalPinToInterrupt(inPin),peakID,RISING); // declarying the interrupt to be triggered
}
void loop() {
* // if(Serial.available()>0){ //Serial communication*
* // dataPy = Serial.readString(); // read the string inside the buffer*
* // dataIn = dataPy.toInt(); // convert income string to int*
* // }*
* incomeData.listen();*
* if(incomeData.isListening()){*
* dataIn = incomeData.read();*

* }*
* actTime = millis(); // actTime stores the amount of time since the program started*

* for(i=0; i<4; i=i+1){*
_ if(actTime - timeout == dataIn){
timeout*=0; //guarantee that the pulse is generated just one time*
* PORTB = 1 << PB0; // HIGH*
* delayMicroseconds(50); // pulse width*
* PORTB = 0 << PB0; // LOW*
PS: dataPy is the value which comes from a Python code and dataIn is its conversion to an integer to be interpreted in Arduino.
Could anyone help me?
Thanks_

To make it easy for people to help you please modify your post and use the code button codeButton.png so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

As well as the Rx -Tx and Tx to Rx connections you also need a GND connection between the Arduinos.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

hey guys

I need to deal with data coming from a Python code to Arduino via USB and this data must be transmmited to another Arduino via TX/RX. I am making use of SoftwareSerial library but I already tried a lot of options to find a solution, but they haven’t worked out fine yet.

Both Arduinos are Nano and I assigned the pins d8 and d9 as rx/tx.

Sender:

void setup() {
  
 pinMode(inPin,INPUT); // set pinD2 up to input
 DDRD = 1 << DDD7; // set pinD7 up to output
 Serial.begin(9600); 
 mySerial.begin(9600);
 attachInterrupt(digitalPinToInterrupt(inPin),peakID,RISING); // declarying the interrupt to be triggered

}


void loop() {

    if(Serial.available()>0){ //Serial communication 
       dataPy = Serial.readString(); // read the string inside the buffer
       dataIn = dataPy.toInt(); // convert income string to int
       mySerial.print(dataIn);
      }

Receiver:

void setup() {
  
 pinMode(inPin,INPUT); // set pinD2 up to input
 DDRD = 1 << DDD7; // set pinD7 up to output
 Serial.begin(9600); 
 mySerial.begin(9600);
 attachInterrupt(digitalPinToInterrupt(inPin),peakID,RISING); // declarying the interrupt to be triggered

}


void loop() {

  // if(Serial.available()>0){ //Serial communication 
  //     dataPy = Serial.readString(); // read the string inside the buffer
  //     dataIn = dataPy.toInt(); // convert income string to int
  //     }
  
    if(mySerial.available()>0){
      dataIn = mySerial.read();
    }

I dont know if it`s something with variable types or code.

Any idea how to solve it?

Thanks

Crespo94:
I dont know if it`s something with variable types or code.

Any idea how to solve it?

You have not told us what your program actually does or what you want it to do that is different.

Have you studied the code in the link I gave you in your earlier Thread ? (I have suggested to the Moderator to merge this with the earlier one).

...R

The idea of my program is:

I'm coupling two oscillator circuits and each one is interacting with one Arduino. The main point is:

As soon as I identify a peak voltage through an interrupt, I need to generate a pulse from the Arduino with a 50us width. However, this pulse must be delayed in some ms, and this delay is being sent from a Python code to Arduino via USB.

What I need to do is: one of my Arduinos is receiving this value and applying it to the pulse it's about to generate. Apart from this, the Arduino 1 must transmit this value to Arduino 2. However, I cant understand how to do that. I have been studying SoftwareSerial library, but without success so far.

I implemented the Example 4 from your Thread, but it didnt work and as requested, I sent a string in order to obtain a integer after atoi()

Crespo94:
I implemented the Example 4 from your Thread, but it didnt work and as requested, I sent a string in order to obtain a integer after atoi()

If you want help you need to post 3 things - the actual program that YOU tried, a sample of the data that you sent to it and the corresponding output from the program.

Without that I don't know what the problem might be.

...R

Code in Arduino IDE

int inPin = 2;
int i;
int dataIn;

volatile unsigned long timeout[4];
volatile int idx = 0;
volatile unsigned long actTime;

const byte numChars = 4;
char receivedChars[numChars];
boolean newData = false;
static byte ndx = 0;
char endMarker = '\n';
char rc;



void setup() {

 pinMode(inPin,INPUT); // set pinD2 up to input
 DDRD = 1 << DDD7; // set pinD7 up to output
 Serial.begin(9600); 
 attachInterrupt(digitalPinToInterrupt(inPin),peakID,RISING); // declarying the interrupt to be triggered

  
}

void loop() {

if(Serial.available()>0){
    rc = Serial.read();
    if(rc!=endMarker){
      receivedChars[ndx] = rc;
      ndx++;
        if(ndx >= numChars){
           ndx = numChars - 1;
        }
    
    }
    else{
      receivedChars[ndx] = '\0';
      ndx = 0;
      newData = true;
      
    }
   
}

    if(newData == true){
    int dataIn = atoi(receivedChars);
    newData = false;
    }

   actTime = millis(); // actTime stores the amount of time since the program started
       
      for(i=0; i<4; i=i+1){
        if(actTime - timeout[i] == dataIn){
          timeout[i]=0; //guarantee that the pulse is generated just one time
          PORTD = 1 << PD7; // HIGH
          delayMicroseconds(50); // pulse width
          PORTD = 0 << PD7; // LOW
          delayMicroseconds(50);
           
        }
        
     }
   
}


void peakID(){ // triggered interrupt

   timeout[idx] = millis(); // assign the time when the interrupt is called to an array
   
   if (idx == 3){ // pointer setup
    idx = 0;
    }
   else{
    idx = idx+1;
   }
   
}

Code in Python

import serial
import time as t

#execute the line that is responsible for the serialcom setup every time close() needed to be run.

   
serialCom = serial.Serial(port = 'COM8', baudrate = 9600, bytesize = serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout=1) #initializing serialCom


tau = 200 #desired delay in ms
serialCom.write(str(tau).encode('ascii')) #write on serialCom


t.sleep(1) #sleep serialCom

#serialCom.close()

The output is attached. What I need: the red wave to be delayed in tau(check Python code)

After this desired delay is set, I need to transmit this tau to another Arduino.

Image from Reply #7 so we don't have to download it. See this Simple Image Guide

...R

You have not provided 2 out of the 3 pieces of information I requested in Reply #6. They are "a sample of the data that you sent to it and the corresponding output from the program."

By "output" I mean the output from the Arduino program.

From a quick look at your Python program I think you are opening and closing the serial port. The Python program needs to open the serial port, allow time for the Arduino to reset before sending any data and then keep the serial port open until it is finished with the Arduino. Have a look at how it is done in this Python - Arduino demo

...R

Hi Robin. Here are examples of what is happening (pictures attached)

Output 1: when I read the values inside the last if. I put into the buffer the number 18 and it was ok.

Output 2: when i read the values outside the last if but inside the largest if. I put into the buffer 18 and it displayed three zeros.

I also tried reading the values outside the largest if and I obtained a non-stop zero generation.

That’s why I am not able to compare the value of dataIn then.

Crespo94:
Hi Robin. Here are examples of what is happening (pictures attached)

I made your earlier image visible and gave you the instructions. Now you please do it for your new images.

I do hope they are not images of text - don’t post images of text, just copy and paste the text.

…R

I solved that problem and I learned now how to post the images, thanks.

The remaining problem is probably regarding the serial data format, because I'm not able to receive the value that I send from Python.

Arduino

rc = Serial.read();

Python:

serialCom = serial.Serial(port = 'COM8', baudrate = 9600, bytesize = serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout=1) #initializing serialCom
t.sleep(2)

tau = 200 #desired delay in ms
serialCom.write(str(tau).encode('ascii'))

Crespo94:
The remaining problem is probably regarding the serial data format, because I'm not able to receive the value that I send from Python.

I believe I covered that fairly comprehensively in Reply #1 and again in Reply #10

...R