Author Topic: 433MHz wireless radios with Digispark  (Read 15491 times)

simmisj

  • Newbie
  • *
  • Posts: 2
433MHz wireless radios with Digispark
« on: June 17, 2013, 10:06:01 am »
Hi.
I am having a problem trying to get 433MHz communication between two Digisparks. I have two Digisparks. One transmitter and the other a receiver.
I simply want to send a binary value (0 or 1) from the transmitter to the receiver but it is not working.
Code for transmitter:
Code: [Select]
#include <MANCHESTER.h>
void setup() {
  pinMode(1, OUTPUT); //LED on Model A 
   
  MANCHESTER.SetTxPin(0);
}
unsigned int transmit_data = 0;
void loop() {
  digitalWrite(1, HIGH);
 
  MANCHESTER.Transmit(transmit_data);
  if(transmit_data == 0)
  {
    transmit_data = 1;
  }
  else
  {
    transmit_data = 0;
  }
  digitalWrite(1, LOW);
 
  //transmit_data += 1;
  delay(1200);
}

 

Code for receiver:
Code: [Select]

 #include <MANCHESTER.h>
#define RxPin 2
void setup() {
  pinMode(1, OUTPUT); //LED on Model A 
  pinMode(5, OUTPUT); //LED on Model A
  // Set digital TX pin
  MANRX_SetRxPin(2);
  // Prepare interrupts
  MANRX_SetupReceive();
  // Begin receiving data
  MANRX_BeginReceive();
  pinMode(0, OUTPUT);
}
unsigned int last_data;
void loop() {
  if (MANRX_ReceiveComplete()) {
    digitalWrite(1, HIGH);
    digitalWrite(5, HIGH);
    unsigned int data = MANRX_GetMessage();
    MANRX_BeginReceive();
    // Handle data...
    if (data == last_data + 1) {
      PINB = 1; // toggle pin 0
    }
    last_data = data;
    digitalWrite(1, LOW);
    digitalWrite(5, LOW);
  }
}
 

I just want to turn on a LED if the value is 1 or turn it off if the value is 0.
Here is a picture of my setup:

Has someone gotten these little cheap 433MHz radios to work with Digispark?
Maybe someone can point me in the right direction?  :)

Bluebie

  • Sr. Member
  • ****
  • Posts: 486
Re: 433MHz wireless radios with Digispark
« Reply #1 on: June 17, 2013, 06:29:14 pm »
If you haven't tried already, try setting the board speed to 16.5, 16.0, and 8, and 1mhz - maybe one will work better than another. Also if you have access to an oscilloscope, see if the receiver is picking up the signal at all.


I've attached two sketches I've used with the digispark, the manchester library, and been quite successful with:


This one is a receiver I used in my backpack to control some ws2811 LEDs, allowing my backpack to mirror the lights from my motorbike (brake and blinker lights specifically)


Code: [Select]
#include <Adafruit_NeoPixel.h>
#include <MANCHESTER.h>


#define RxPin 1
#define PixelPin 3
#define TotalPixels 6
Adafruit_NeoPixel lights = Adafruit_NeoPixel(TotalPixels, PixelPin, NEO_GRB + NEO_KHZ400);


// color constructor
#define c(a,b,c) lights.Color(a,c,b)
#define BlinkerOrange c(255,60,0)
#define BrakeRed c(255,0,0)
#define IdleRed c(50,0,0)
#define Black c(0,0,0)


#define LightingTimeout 2250 /* 2.25 seconds till timeout */


void setup() {
  lights.begin();
  lights.show();
 
  pinMode(0, OUTPUT);
 
  // power the radio receiver
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW); // gnd
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH); // vcc
 
  // Set digital TX pin
  MANRX_SetRxPin(RxPin);
  // Prepare interrupts
  MANRX_SetupReceive();
  // Begin receiving data
  MANRX_BeginReceive();
}


void set_all_pixels(uint32_t color) {
  set_left_ear(color);
  set_right_ear(color);
}


void set_left_ear(uint32_t color) {
  lights.setPixelColor(0, color);
  lights.setPixelColor(1, color);
  lights.setPixelColor(2, color);
}


void set_right_ear(uint32_t color) {
  lights.setPixelColor(3, color);
  lights.setPixelColor(4, color);
  lights.setPixelColor(5, color);
}


void on_lights_change(byte data) {
  boolean brake = (data >> 0) & 1;
  boolean left_blinker = (data >> 1) & 1 ;
  boolean right_blinker = (data >> 2) & 1;
  boolean system_powered = (data >> 3) & 1;
 
  set_all_pixels(system_powered? IdleRed : Black);
  if (brake) set_all_pixels(BrakeRed);
  if (left_blinker)  set_left_ear(BlinkerOrange);
  if (right_blinker) set_right_ear(BlinkerOrange);
 
  lights.show(); // send out update to LEDs
}


void on_battery_level_change(unsigned int measurement) {
  // TODO: Detect low levels and visualise somehow?
}


byte last_lights;
unsigned int last_battery;
void loop() {
 
  if (MANRX_ReceiveComplete()) {
    unsigned int data = MANRX_GetMessage();
    MANRX_BeginReceive();
    // Handle data...
    //if (data >> 8 == 0xab49) { // this is a lights update
      byte lights = data & 0xFF;
      //if (last_lights != lights)
      on_lights_change(lights);
      last_lights = lights;
      PINB = 1;
    //}// else if (data & 0xFFF0000 == 0xEB900000) { // is a battery level update
    //  unsigned int battery = data & 0xFFF;
    //  if (last_battery != battery) on_battery_level_change(battery);
    //  last_battery = battery;
    //}
  }
}

[size=78%]and the transmitter:[/size]

Code: [Select]

#include <MANCHESTER.h>


// transmit runs for about 65ms on the radio, so at two updates per second
// this is 13% channel utilisation, which is pretty nice to other users
#define RETRANSMIT_INTERVAL 500 /* retransmit every 0.5 seconds when idle */
#define RETRANSMIT_BATTERY_INTERVAL 10000 /* every 10 seconds */
#define BATT_LVL_ADC_CHANNEL 2 /* channel 2, pin 4 */


void setup() {
  MANCHESTER.SetTxPin(0);
  pinMode(1, INPUT);
  pinMode(2, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
}


byte lights_state() {
  byte value = 0;
  if (digitalRead(5)) value |= _BV(0); // brake active?
  if (digitalRead(1)) value |= _BV(1); // left blinker active?
  if (digitalRead(2)) value |= _BV(2); // right blinker active?
  //if (digitalRead(4)) // system power on? (ADC2)
  value |= _BV(3); // detection doesn't seem to work... so hardcode yes
 
  return value;
}


boolean is_active() {
  static unsigned long last_active;
  unsigned long time_now = millis();
  byte lights = lights_state();
  if ((lights & 0b0111) != 0) last_active = time_now;
  return (time_now - last_active < RETRANSMIT_INTERVAL);
}


unsigned long last_transmit_time = 0;
void transmit_state() {
  unsigned long time_now = millis();
  unsigned int time_since_transmit = time_now - last_transmit_time;
 
  byte state = lights_state();
  if (is_active() || time_since_transmit > RETRANSMIT_INTERVAL) {
    last_transmit_time = time_now;
   
    MANCHESTER.Transmit(0xab490000 | state);
  }
}


unsigned long last_battery_time = 0;
void transmit_battery_level() {
  unsigned long time_now = millis();
  unsigned int time_since = time_now - last_battery_time;
  if (time_since > RETRANSMIT_BATTERY_INTERVAL) {
    unsigned int analog_reading = analogRead(BATT_LVL_ADC_CHANNEL);
    byte message = 0xeb900000 | analog_reading;
    MANCHESTER.Transmit(message);
    last_battery_time = time_now;
  }
}


void loop() {
  transmit_state();
  //transmit_battery_level();
}

[size=78%]It worked well, but I found it needed line of sight to work whenever there weren't lots of walls nearby for the radio waves to bounce off. This line of sight requirement has me convinced it'd be better to use infrared in the future, and I stopped using it because unreliable lights seem worse than no lights to me.[/size]

Mark

  • Full Member
  • ***
  • Posts: 196
Re: 433MHz wireless radios with Digispark
« Reply #2 on: June 18, 2013, 03:17:00 am »
I 've used 433Mhz Tx with Digispark, but I didn't really test the range.
http://digistump.com/board/index.php/topic,371.0/topicseen.html

Two things from your photo:-
  • You should straighten your antenna out, so it actually radiates properly
  • You also need to space the Tx and Rx further apart, as they will be de-tuning each other that close together.
RF needs 1 wavelength to start becoming an electromagnetic wave which at 433MHz is 680-700mm (26-27.5 inches)
see http://en.wikipedia.org/wiki/Near_and_far_field

I haven't tried the manchester.h library, but you normally send a preamble which consists of 1,0,1,0,1,0 to wakeup and lock the rx onto the incoming signal.



Mark

Bluebie

  • Sr. Member
  • ****
  • Posts: 486
Re: 433MHz wireless radios with Digispark
« Reply #3 on: June 19, 2013, 05:09:45 pm »
The manchester library does send that preamble. It is designed for these sort of radios.

Mark

  • Full Member
  • ***
  • Posts: 196
Re: 433MHz wireless radios with Digispark
« Reply #4 on: June 20, 2013, 01:59:09 am »
Bluebie

Thanks for that.
So do they automatically send something to lock the Rx to the Tx?

mark


dougal

  • Sr. Member
  • ****
  • Posts: 289
Re: 433MHz wireless radios with Digispark
« Reply #5 on: June 20, 2013, 07:59:22 am »
AFAIK, the Manchester lib is lower-level than that. The radios just operate in a broadcast sort of mode. If you want to implement targeted messaging, you'll have to come up with your own protocol for that in your send/receive code. The easiest way would probably be to designate the first byte or two of each message as a unit identifier.


https://github.com/Bluebie/arduino-libs-manchester