Communicating two rpm data between two Arduino boards with Analog pin

Hi everyone, my project is composed by :

  • reading two rpm data on one Arduino Uno Board with Software Serial library
  • after that sending these data to the other Arduino Uno with Analog Pins.

I want to do this communication in order to make a comparison between two rpm data for regulate motors if one is faster than other.

I can't use the serial communication else I can't decode Rpm data.

So my configuration is :

Arduino "RPMs" : pin A1 and A3 sending rpm data to the other Arduino with AnalogWrite
Arduino "Motors" : pin A1 and A2 receiving rpm data with AnalogRead
Both Arduino Board are powered by usb and connected in common by GND.

Code for Arduino "RPMs" : SENDING DATA
int send_rpmG = A1;
int send_rpmD = A3;

// rpmG_value and rpmD_value have been converted to a range 0-255

void loop(){
analogWrite(send_rpmG,(rpmG_value)); Serial.print(rpmG_value); Serial.print("\n");
analogWrite(send_rpmD,(rpmD_value)); Serial.print(rpmD_value); Serial.print("\n");
}

Code for Arduino "MOTORs" : RECEIVING DATA
int rpmG=0, rpmD=0;

void loop(){
rpmG = analogRead(A1);
rpmD = analogRead(A2);
Serial.print("\t Rpm G : "); Serial.print(rpmG);Serial.print("\t \t Rpm D : "); Serial.print(rpmD);Serial.print(" \n");
}

I can't figure out a solution to communicate between two boards without use serial communication in order to not avoid decoding rpm data.
Sorry for my english,
I stay available.

You can't use analogWrite() on the analog pins. They are for analogRead(). analogWrite() only works on the PWM pins and it does not provide an effect that can be meaningfully tested with analogRead() because PWM is just a sequence of HIGH and LOW values.

If you want to compare motor speeds then you need hardware to measure the speed of the motors - for example an optical detector that produces a pulse every time the motor rotates and then you Arduino can measure the time between pulses to figure out the speed.

If your Arduinos both calculate the number of microseconds for each revolution they can easily compare the data if one of them sends its value to the other.

...R
Serial Input Basics - simple reliable ways to receive data.

Ok for that, my mistake. Thank you.
I corrected that and modified Arduino_Rpms’s pins A1 and A3 to pin 3 and pin 6.
I obtain on Arduino Motors value which are 0 or 1023.

To explain more my project, I use FrskySport library in order to decode Rpms.
As I said before, I have to read two rpm values from two different motors and regulate them if one or the other is faster.

But I can’t decode rpm data and control motors with an unique board, because if they have interrupted, decoding rpm data doesn’t work.
So, I decided to control motors on one Arduino Board, decode rpm data on another Arduino Board and send these values to the first one.

It’s working well for the motor control, but I can’t read rpm in same time.
Because, it’s interrupted decoding rpm data.
Nevertheless, I can read rpm data on the Arduino Rpm but I can’t send these data to the other Arduino.
In order to see my project, I attached a picture. It’s the schema with sending data via analog pins…

“Arduino Rpms” : send rpm values

#define POLLING_ENABLED
#include "FrSkySportSensor.h"
#include "FrSkySportSensorRpm.h"
#include "FrSkySportSingleWireSerial.h"
#include "FrSkySportDecoder.h"
#if !defined(__MK20DX128__) && !defined(__MK20DX256__) && !defined(__MKL26Z64__) && !defined(__MK66FX1M0__) && !defined(__MK64FX512__)
#include "SoftwareSerial.h"
#endif

FrSkySportSensorRpm rpmG;                               // Create RPM sensor with default ID
FrSkySportSensorRpm rpmD(FrSkySportSensor::ID10);  // Create FLVSS sensor with given ID 

#ifdef POLLING_ENABLED
  FrSkySportDecoder decoder(true);                     // Create decoder object with polling
#else
  FrSkySportDecoder decoder;                           // Create decoder object without polling
#endif

uint32_t currentTime, displayTime;
uint16_t decodeResult;
int send_rpmG = 3; 
int send_rpmD = 6; 

int rpmG_send = 0,rpmD_send = 0;

void setup()
{
  pinMode(send_rpmG, OUTPUT);
  pinMode(send_rpmD, OUTPUT);
  
  decoder.begin(FrSkySportSingleWireSerial::SOFT_SERIAL_PIN_11, &rpmG,&rpmD);
  
  Serial.begin(9600);
}

void loop()
{
  // Read and decode the telemetry data, note that the data will only be decoded for sensors
  // that that have been passed to the begin method. Print the AppID of the decoded data.
  decodeResult = decoder.decode();
  if(decodeResult != SENSOR_NO_DATA_ID) { Serial.print("Decoded data with AppID 0x"); Serial.println(decodeResult, HEX); }

  // Display data once a second to not interfeere with data decoding
  currentTime = millis();
  if(currentTime > displayTime)
  {
    displayTime = currentTime + 1000;

    Serial.println("");
  
    // Get RPM/temperature sensor data
    Serial.print("RPM: rpmG = "); Serial.print(rpmG.getRpm());                              // Rotations per minute
    Serial.print(", T1 = "); Serial.print(rpmG.getT1());                                   // Temperature #1 in degrees Celsuis (can be negative, will be rounded)
    Serial.print(" deg. C, T2 = "); Serial.print(rpmG.getT2()); Serial.println(" deg. C"); // Temperature #2 in degrees Celsuis (can be negative, will be rounded)
    
    Serial.print("RPM: rpmD= "); Serial.print(rpmD.getRpm());                              // Rotations per minute
    Serial.print(", T1 = "); Serial.print(rpmD.getT1());                                   // Temperature #1 in degrees Celsuis (can be negative, will be rounded)
    Serial.print(" deg. C, T2 = "); Serial.print(rpmD.getT2()); Serial.println(" deg. C"); // Temperature #2 in degrees Celsuis (can be negative, will be rounded)

    Serial.println("");
    
    analogWrite(send_rpmG,(rpmG_send/8)); Serial.print(rpmG_send/8); Serial.print("\n"); 
    analogWrite(send_rpmD,(rpmD_send/8)); Serial.print(rpmD_send/8); Serial.print("\n");
  }
}

“Arduino Motors” : receive rpm values

#include <Servo.h>
int channel;
Servo EscG;
Servo EscD;
int rpmG = 0; 
int rpmD = 0;

void setup(){
  //// SET ESC OUTPUTS ////
  pinMode(5,OUTPUT); 
  pinMode(9, OUTPUT); 
  EscG.attach(5);
  EscD.attach(9);
  Serial.begin(9600);
  EscG.writeMicroseconds(900);
  EscD.writeMicroseconds(900); 
  delay(1500); 
}

void writeToEscs(int val) {
  EscG.writeMicroseconds(val);
  EscD.writeMicroseconds(val);
  delay(10);
}

void initEsc(String message) {
  Serial.print(message);
  Serial.println(intRead); Serial.print(" Mise à zéro.. \n");
  writeToEscs(1500);
}

void loop() {
  
  rpmG = analogRead(A1); 
  rpmD = analogRead(A2);

  Serial.print("\t Rpm G : ");  Serial.print(rpmG);Serial.print("\t \t Rpm D : "); Serial.print(rpmD);Serial.print(" \n");
  writeToEscs(1500); 
  
}

If you have any idea in order to transmit these rpm values, I will really greatful…
Thank you for all.

schema2.png

Please read:

  1. Robin2’s post again

  2. analogWrite()

Then you will understand why you only get values of 0 and 1023.

I will leave you with this piece of information, the Arduino UNO and MEGA contain only ADCs, they do not contain any DACs. What you are trying to do will not work without the purchase and addition of a DAC.

To send the data to the other Arduino do something like this

mySerial.print('<'); // start marker
mySerial.print(rpmG_send);
mySerial.print(','); // comma separator
mySerial.print(rpmD_send);
mySerial.println('>'); // end marker

using SoftwareSerial to create an extra serial port on both Arduinos. I have called it mySerial in above the snippet.

Alternatively, if the two Arduinos are close together, use I2C or SPI to tansfer the data as it will be quicker.

…R

Thank you for your answers.

I tried to use Software Serial and create an extra serial port, using TX and RX.
Nevertheless, as soon as I declare : "mySerial.begin(xxx); ", rpms can’t be decoded and whatever the baudrate provided for this extra serial port…

After that I tried to make a communication with the I2C protocol with pins A4/A5 and the common GND.

I followed the principle : Master Reading (Arduino Motor)/Slave Sending (Arduino Rpm), in order to not have in the void loop of the Slave/Arduino_Rpm “begin… end transmission” which avoids the rpm data decoding.

Code added to Arduino_Rpmin loop / Slave sender

    Wire.write('<');
    Wire.write(rpmG_send);
    Wire.write(',');
    Wire.write(rpmD_send);
    Wire.write('>');

Code added to Arduino_Motor in loop / Master reader

  Wire.requestFrom(8, 6);
  Serial.print(Wire.read());Serial.print("\n");

So I obtained data between 70-85, there are random data, fluctuating, but with no noticeable change with rpm data… did I make a mistake somewhere ?

Else, I read your post adwsystems, but I don’t have an Operational Amplifier to make a DAC myself.
But the solution would be to buy an Arduino DUE in order to remplace Arduino Motor (UNO) and to do an “analogRead()” on pins contain DACs ?

arthy:
Else, I read your post adwsystems, but I don’t have an Operational Amplifier to make a DAC myself.
But the solution would be to buy an Arduino DUE in order to remplace Arduino Motor (UNO) and to do an “analogRead()” on pins contain DACs ?

There is more to a DAC than an opamp. An Arduino Due would work, or purchase a DAC and add it on.

SparkFun I2C DAC Breakout - MCP4725 $5

And you would do an analogWrite() to the DAC on the Due. (write to outputs, read from inputs)

arthy:
Thank you for your answers.

I tried to use Software Serial and create an extra serial port, using TX and RX.
Nevertheless, as soon as I declare : "mySerial.begin(xxx); ", rpms can't be decoded and whatever the ba

Maybe the FrSky library does not work well with other Arduino libraries - that is not an uncommon problem.

I am not familiar with FrSky, what is it for and how does it do it?

...R

I will certainly buy an Arduino DUE and a DAC, thanks adwsystems.

Robin2 : I use the FrSky Library which is (as its name) useful for the rpm data reading which are Fr SKy Rpm sensors, both of them...
You could have more information on this Library here : https://www.rcgroups.com/forums/showthread.php?2245978-FrSky-S-Port-telemetry-library-easy-to-use-and-configurable

I have one more question : why do I obtain random values around 70-80 for master/slave with the i2c communication ?

Arthy.

You only need either the Due or Sparkfun DAC.

adwsystems:
You only need either the Due or Sparkfun DAC.

adwsystems:
There is more to a DAC than an opamp. An Arduino Due would work, or purchase a DAC and add it on.

SparkFun I2C DAC Breakout - MCP4725 $5

And you would do an analogWrite() to the DAC on the Due. (write to outputs, read from inputs)

Hi, so I finally receive the Arduino DUE ordered,
I am doing an AnalogWrite() since the Arduino RPM (UNO) on pins 3 / 6 (PWM),
and I am reading with AnalogRead(DACx) on the Arduino DUE on pins DAC0 and DAC1. But I don't have any values : always 0.

What am I doing wrong ?

The same thing you were doing before and then some. Mostly not reading the available information.

You even posted what you are doing wrong.

arthy:
I am doing an AnalogWrite() since the Arduino RPM (UNO) on pins 3 / 6 (PWM),

adwsystems:
And you would do an analogWrite() to the DAC on the Due. (write to outputs, read from inputs)

arthy:
I am reading with AnalogRead(DACx) on the Arduino DUE on pins DAC0 and DAC1

These lines aren't the same. The first is correct, the second is not.

  1. Again you are doing an analogWrite() on the UNO to a PWM pin. The analogWrite() on the UNO DOES NOT produce a 0 to 5 volt output, it produces a train of 0 or 5 volt pulses of varying width.

  2. You are doing a (digital) analogRead() of a Digital-to-Analog Converter (DAC).

So:

  1. Re-read the previous link on the use of analogWrite() on the UNO.
  2. Read up on what PWM is
  3. Swap the boards. Get the analogRead() on the UNO from the ADC pins. Get the command to write to the DAC on the Due. (I don't know what it is and I don't have a Due to find out).