Transmitting PWM from one board to another

I’m experimenting with having Arduino 1 measure a distance using an ultrasonic sensor, if the value is less than 50, it sends back a PWM signal with a duty cycle X to Arduino 2. If it’s more than 51, it sends back a PWM signal with a duty cycle of Y to Arduino 2.

Arduino 2 then is supposed to read the PWM duty cycle, and report on my LCD using an if statement. I’d appreciate any help on this. Right now using this code I only get" Distance above 50" and no change no matter how close I get to the sensor.

(right now the 50 is just a unit and I’ll change these units once I have the code working)

Sensor reading arduino code:

#include <Wire.h>



//
// defines pins numbers
const int trigPin = A3;
const int echoPin = A0;
const int alarmPin = 2;
const int pwmOut = A4;
// defines variables
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(4, OUTPUT);
Serial.begin(9600); // Starts the serial communication
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);;
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);

// Calculating the distance
distance= duration*0.034/2;

Serial.print("D");
Serial.println(distance);
if (distance > 50) analogWrite(pwmOut, 255);
if (distance < 50) analogWrite(pwmOut, 50);
noTone(alarmPin);

}

PWM Reading Arduino

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);


//

void setup() {
  Serial.begin(9600); 
  pinMode(2,INPUT_PULLUP);
  pinMode(3,INPUT_PULLUP);
  pinMode(13, OUTPUT);
  digitalWrite(13,HIGH);
  int val = 0;
  delay(500);
  lcd.init();
  lcd.backlight();
  Serial.print("Initializing Startup");
  lcd.setCursor(2, 0); 
  lcd.print("Initializing"); 
  lcd.setCursor(2, 1); 
  lcd.print("Start Up...");
  delay(3000);
  Serial.print("Testing Connections");
  lcd.setCursor(2, 0); 
  lcd.print("Testing Sensor"); 
  lcd.setCursor(2, 1); 
  lcd.print("connections...");
  delay(3000);
if (digitalRead(2) == HIGH) {
    lcd.setCursor(2, 0);
   lcd.print("Sensor 1      ");
   lcd.setCursor(2, 1);
   lcd.print("connected     ");
   
}
 delay(3000);
if (digitalRead(3) == HIGH) {
   lcd.setCursor(2, 0);
   lcd.print("Sensor 2      ");
   lcd.setCursor(2, 1);
   lcd.print("connected     ");
   if (digitalRead(3) == LOW) 
   lcd.setCursor(2, 0);
   lcd.print("Sensor 2      ");
   lcd.setCursor(2, 1);
   lcd.print("not connected  ");
}
 delay(3000);
 lcd.setCursor(2, 0);
   lcd.print("Test finished ");
   lcd.setCursor(2, 1);
   lcd.print("                ");
   delay(3000);
   lcd.setCursor(2, 0);
   lcd.print("Starting       ");
    lcd.setCursor(2, 1);
     lcd.print("monitors        ");
       // Turn off the display:
  lcd.noDisplay();
  delay(500);
  // Turn on the display:
  lcd.display();
  delay(500);
     
  //
  
}

void loop() {
  // Turn off the display:
  lcd.clear();
  delay(500);
  analogRead(A2);{
  if (A2 <= 100){ lcd.setCursor(2, 0);
     lcd.print("Distance");
     lcd.setCursor(2, 1);
     lcd.print("below 50");
      lcd.clear();
     if (A2 > 100) lcd.setCursor(2, 0);
     lcd.print("Distance");
     lcd.setCursor(2, 1);
     lcd.print("above 50");
     delay(2500);
     lcd.clear();
      
}
}

}

Mind your braces.

In loop(), your second if statements is entirely within your first, A2 will never be greater than 100 there, it’s already been determined by you logic to be less than or equal to 100.

HTH

a7

You may have better luck using the pulseIn() function to read the PWM signal. The analogRead() function is not going to work. PWM is not analog despite the, unfortunately named, analogWrite() function. PWM is a digital signaland the level of the signal is 0 or 1, nothing in between. It is the duty cycle (pulse width) that changes. The pulseIn() function will measure the pulse width.

const int pwmOut = A4;

A4 is not a PWM pin on any Arduino board that I know of. What boards are you using?

Your code would be easier to follow (read) if you were to format the code with the IDE autoformat tool (ctrl-t or Tools, Auto Format).

Instead of sending a PWM signal to Arduino 2, consider sending a value (by serial, for example), and have Arduino 2 report that.

groundFungus:
Your code would be easier to follow (read) if you were to format the code with the IDE autoformat tool (ctrl-t or Tools, Auto Format).

@groundFungus, right THX, shoulda said. I couldn’t remember the command. Easier to read and easier to spot logic errors, which here go beyond the aforementioned.

a7

groundFungus:
You may have better luck using the pulseIn() function to read the PWM signal. The analogRead() function is not going to work. PWM is not analog despite the, unfortunately named, analogWrite() function. PWM is a digital signaland the level of the signal is 0 or 1, nothing in between. It is the duty cycle (pulse width) that changes. The pulseIn() function will measure the pulse width.

const int pwmOut = A4;

A4 is not a PWM pin on any Arduino board that I know of. What boards are you using?

Your code would be easier to follow (read) if you were to format the code with the IDE autoformat tool (ctrl-t or Tools, Auto Format).

Sort of got it working, I’ve fixed braces, reformatted and began to use the pulseIn function. I also added a serial.Print to see what my PulseIn value is. Pulse value is consistently 10801080. Not sure why.

Also changed to A2, for the Nano PWM Pin
new codes:

Sensor Reader

#include <Wire.h>



//
// defines pins numbers
const int trigPin = A3;
const int echoPin = A0;
const int alarmPin = 2;
const int pwmOut = 3;
// defines variables
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(4, OUTPUT);
Serial.begin(9600); // Starts the serial communication
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);;
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);

// Calculating the distance
distance= duration*0.034/2;

Serial.print("D");
Serial.println(distance);
if (distance > 100) analogWrite(pwmOut, 255);
if (distance < 50) analogWrite(pwmOut, 0);
noTone(alarmPin);

}

Master

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);


//

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  int pwmSig = (pulseIn);
  int val = 0;
  delay(500);
  lcd.init();
  lcd.backlight();
  Serial.print("Initializing Startup");
  lcd.setCursor(2, 0);
  lcd.print("Initializing");
  lcd.setCursor(2, 1);
  lcd.print("Start Up...");
  delay(3000);
  Serial.print("Testing Connections");
  lcd.setCursor(2, 0);
  lcd.print("Testing Sensor");
  lcd.setCursor(2, 1);
  lcd.print("connections...");
  delay(3000);
  if (digitalRead(2) == HIGH) {
    lcd.setCursor(2, 0);
    lcd.print("Sensor 1      ");
    lcd.setCursor(2, 1);
    lcd.print("connected     ");

  }
  delay(3000);
  if (digitalRead(3) == HIGH) {
    lcd.setCursor(2, 0);
    lcd.print("Sensor 2      ");
    lcd.setCursor(2, 1);
    lcd.print("connected     ");
    if (digitalRead(3) == LOW)
      lcd.setCursor(2, 0);
    lcd.print("Sensor 2      ");
    lcd.setCursor(2, 1);
    lcd.print("not connected  ");
  }
  delay(3000);
  lcd.setCursor(2, 0);
  lcd.print("Test finished ");
  lcd.setCursor(2, 1);
  lcd.print("                ");
  delay(3000);
  lcd.setCursor(2, 0);
  lcd.print("Starting       ");
  lcd.setCursor(2, 1);
  lcd.print("monitors        ");
  delay(2000);
  lcd.noDisplay();

  // Turn on the display:
  lcd.display();
  delay(500);

  //

}

void loop() {
  int pwmSig = (pulseIn);
  // Turn off the display:
  lcd.clear();
  delay(500);
  pulseIn(A2, HIGH, 1000); {
    if (pulseIn < 100);
    lcd.setCursor(2, 0);
    lcd.print("Distance");
    lcd.setCursor(2, 1);
    lcd.print("below 50");
    Serial.print(pwmSig);

    lcd.clear();

    pulseIn(A2, HIGH, 1000);
    if (pulseIn > 100) {
      lcd.setCursor(2, 0);
      lcd.print("Distance");
      lcd.setCursor(2, 1);
      lcd.print("above 50");
      Serial.print(pwmSig);
    }

    delay(2500);
    lcd.clear();

  }
}

Michibacy:

Serial.print("D");

Serial.println(distance);
if (distance > 100) analogWrite(pwmOut, 255);
if (distance < 50) analogWrite(pwmOut, 0);
noTone(alarmPin);

}

Using analogWrite() is not an efficient way to send data from one Arduino to another.

As you are using Serial to print the distance why not just connect things up so that the other Arduino also receives the distance value.

Or if you want to keep things separate use SoftwareSerial to create an extra serial port on two other I/O pins and use something like mySerial.write(255); or mySerial.write(0); - or any other value that can be used with analogWrite().

Be aware that analogWrite(pin, 255); is the same as digitalWrite(pin, 1); and analogWrite(pin, 0) is the same as digitalWrite(pin, 0);

…R

Using analogWrite() is not an efficient way to send data from one Arduino to another.

I agree with that, but I try to answer the OP question. I would use serial, but they may want the learning experience.

Also changed to A2, for the Nano PWM Pin

A2 is not a PWM pin either. The PWM pins on a Nano are 3, 5, 6, 9, 10, 11. The A pins are analog inputs, not outputs and PWM is not analog, anyway.

Pulse value is consistently 10801080

Aside from the fact that you are not really sending PWM the readings are running together. Use println() instead of print so the readings are separated by line feeds.

In your master, these lines look incorrect.

pulseIn(A2, HIGH, 1000); {
if (pulseIn < 100);
lcd.setCursor(2, 0);

the semicolon at the end of the if statement completes the syntax. There is no code being selected or skipped based on that test, the semicolon is the entire statement controlled. An empty statement.

You should look through some more example code to get a feel for this easy to make but subtle and harder to spot kind of mistake.

Compiler warnings turned way up may also draw your attention to this and other such things it thinks you mightn’t have meant.

a7

As far as I know pulseIn() won't work with analogWrite(pin, 255) or analogWrite(pin, 0) because neither produces a pulsing output.

...R

Hi
WHY do you need two Arduino controllers?
One controller will do it all.

Thanks.. Tom... :slight_smile:
PS. I can't believe this was not the first question asked..... :o :o :o :o

Michibacy:

if (distance > 100) analogWrite(pwmOut, 255);

if (distance < 50) analogWrite(pwmOut, 0);

Even though pin 3 is indeed a PWM pin, this still doesn’t give you a PWM signal.

These lines do the exact same thing:

if (distance > 100) digitalWrite(pwmOut, HIGH);
if (distance < 50) digitalWrite(pwmOut, LOW);

TomGeorge:
PS. I can't believe this was not the first question asked..... :o :o :o :o

Probably because I did not take an interest in it! :astonished:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.