RadioHead and Blinking LED

Hi everyone. A relative Arduino newbie here. I’m doing a wireless transmission of a signal to blink an LED with the millis() function, using RadioHead. I’m using the millis() because I would like to change the frequency of the blinking and the duty cycle of each blink, so that it could be used as a wireless strobe light.

I already have the actual code up and running on one Pro Mini, and am trying to add the RadioHead library. However, I am unable to make the receiver blink at all.

Here is the transmitter code I made so far.

#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile
RH_ASK transmit; 

#include <LiquidCrystal.h>
#define mosfet 13       // mosfet
#define RS 9       // LCD RS pin, may be moved
#define E 8         // LCD E or encode pin, may be moved
#define D4 7        // LCD D4 pin, may be moved
#define D5 6        // LCD D5 pin, may be moved
#define D6 5        // LCD D6 pin, may be moved
#define D7 4        // LCD D7 pin, may be moved

LiquidCrystal lcd (RS, E, D4, D5, D6, D7); 

byte arrow[8] = {  //creates the arrow
  0b10000,
  0b11000,
  0b11100,
  0b11110,
  0b11110,
  0b11100,
  0b11000,
  0b10000
};
int freq;
long period;
int onPct;
long onTime;
long startTime;
long timeNow;

#define encoderA 3
#define encoderB 2
#define encoderSwitch 11

int pin[3] = {encoderA, encoderB, encoderSwitch};
boolean mode;
volatile boolean turn;
volatile boolean down;
volatile boolean pressed;

// display data function 
void displayData () {
  lcd.setCursor(1, 0);
  lcd.print("Frequency: ");
  lcd.print(freq);
  lcd.setCursor(1, 1);
  lcd.print("On%: ");
  lcd.print(onPct);
  lcd.print("%");
}
// display arrow function
void arrowDisplay() {
  lcd.begin(16, 2);
  if (mode == 1) {
    lcd.setCursor(0, 0);
    lcd.write((uint8_t)0);
  }
  else {
    lcd.setCursor(0, 1);
    lcd.write((uint8_t)0);
  }
}
// blink mosfet / LED 

void blinker () {
  period = 1000 / freq;
  onTime = 10 * onPct / freq;
  timeNow = millis ();

  if (timeNow - startTime >= period) {
    startTime = timeNow;
  }

    if (timeNow - startTime <= onTime) {
      digitalWrite (mosfet, HIGH);
      transmit.send((uint8_t *)high, strlen(high)); // added after testing rest of code
      transmit.waitPacketSent(); // added after testing rest of code
      delay(0); // added after testing rest of code
    }
    else {
      digitalWrite (mosfet, LOW);
      transmit.send((uint8_t *)low, strlen(low)); // added after testing rest of code
      transmit.waitPacketSent(); // added after testing rest of code
      delay(0); // added after testing rest of code
    }
}
void setup () {

Serial.begin (9600);
  
  // pinmodes
  pinMode (pin[3], INPUT);

  // set lcd
  lcd.begin (16, 2);
  lcd.createChar (0, arrow);

  // set initial values
  freq = 10;
  onPct = 30;
  mode = 1;
  startTime = 0;

  //display data on LCD
  arrowDisplay();
  displayData ();

  //interrupt
  attachInterrupt (digitalPinToInterrupt(encoderB), senseTurn, CHANGE);
  attachInterrupt (digitalPinToInterrupt(encoderSwitch), sensePress, FALLING);
}

void loop () {
const char *high = "1"; // added after testing rest of code
const char *low = "0"; // added after testing rest of code

Serial.println (freq);
Serial.println (onPct);

period = 1000 / freq;
onTime = onPct*period; 

  if (pressed == true) {
    mode = !mode;
    arrowDisplay();
    displayData();
    delay (50);
    pressed = false;
  }
  
  if (turn && mode == 1) {
    if (down) {
      if (freq >= 200) {
        freq = 200;
        arrowDisplay ();
        displayData ();
        delay (50);
      }
      else {
        freq ++;
        arrowDisplay ();
        displayData ();
        delay (50);
        }
    }
    else {
      if (freq <= 1) {
        freq = 1;
        arrowDisplay ();
        displayData ();
        delay (50);
        }
      else {
        freq --;
        arrowDisplay ();
        displayData ();
        delay (50);
        }
    }
    turn = false;
  }

  if (turn && mode == 0) {
    if (down) {
      if (onPct >= 100) {
        onPct = 100;
        arrowDisplay ();
        displayData ();
        delay (50);
        }
      else {
        onPct ++;
        arrowDisplay ();
        displayData ();
        delay (50);
        }
    }
    else {
      if (onPct <= 1) {
        onPct = 1;
        arrowDisplay ();
        displayData ();
        delay (50);
        }
      else {
        onPct --;
        arrowDisplay ();
        displayData ();
        delay (50);
        }
    }
    turn = false;
  }
blinker ();
}

// interrupts ***************************************************************************************************************************************

void senseTurn ()  {
  turn = true;
  down = (digitalRead(encoderA) == digitalRead(encoderB));
}

void sensePress ()  {
  7pressed = true;
 }

I am using the example in the IDE as the basis for the receiver code.

Any help or useful comments will be much appreciated! Thanks :slight_smile:

It is a good idea to get all the individual pieces of a program working before lumping them all together.

Write a very simple transmitter program that just uses RadioHead to send the blink parameters to the receiver and debug that. Even before you do that, get the simple examples in the RadioHead library working.

Note: all times associated with millis() or micros() should be declared unsigned long.

long onTime;
long startTime;
long timeNow;

jremington:
It is a good idea to get all the individual pieces of a program working before lumping them all together.

Write a very simple transmitter program that just uses RadioHead to send the blink parameters to the receiver and debug that. Even before you do that, get the simple examples in the RadioHead library working.

Note: all times associated with millis() or micros() should be declared unsigned long.

long onTime;

long startTime;
long timeNow;

I have done all parts of the code, and they all worked flawlessly. I 've also tried lumping all of the components together, without the RH portion, and that also worked.

However, when I put the RH code into the code, the LED won't work.

I've also tried working it backwards from RH, I placed the millis() portion in first, and the LED won't blink.

I'll try changing the code tomorrow, as it is quite late here. Thanks for the input, and hope they work :slight_smile:

What is the MOSFET switching and how is it wired? It is possible that it is introducing a power glitch that interferes with transmission. Please post the your circuit diagram (hand drawn, not Fritzing).

      digitalWrite (mosfet, HIGH);
      transmit.send((uint8_t *)high, strlen(high)); // added after testing rest of code
      transmit.waitPacketSent(); // added after testing rest of code
      delay(0); // added after testing rest of code

What is that idiotic delay(0) doing there?

I haven't connected anything yet at this point. I'm still using the built-in LED to test if transmission and reception occurs.

I'm reworking the code again, starting with the code for RH_ASK.

So far, I figured these out:

  1. The wireless system works with the millis() function, but is limited to a maximum frequency of 14 Hz.
  2. inserting the interrupt code does not disrupt the blink code.
  3. inserting the lcd code does not disrupt the blink code.

I guess it was a case of bad coding. My bad :slight_smile: Also, I guess it was something about the limit of the frequency being there.

Thanks for the input. :slight_smile:

but is limited to a maximum frequency of 14 Hz.

The human eye can't detect blinks at frequencies much higher than that. What is your intent with this project?

The code below limits you to integer milliseconds for the timing, but one millisecond is a long time for the Arduino.

  period = 1000 / freq;
  onTime = 10 * onPct / freq;