Category Archives: Arduino

Arduino simple 433Mhz/315Mhz remote control(transmitter & receiver)

I decided to create probably the simplest and cheapest remote control which is compatible with the rest of the commercial RC equipment. The remote control purpose is to be cheap, simple and fast enough for ground equipment such as RC cars, tanks, rovers, robots, etc.  If the remote proves to be reliable and more important fast enough it can be used for flying stuff like quad copters and other single and multi rotor equipment.I am bringing up the speed topic because I will be doing a lot of DA and AD conversions which will need time. In my initial tests the remote control response time is 1/15 seconds which should be enough speed for most ground vehicles.

The remote control is again based on those cheap ASK 315/433Mhz modules and Arduino to keep the cost low. I will be using the 433Mhz modules since I found great and cheap antennas for them only and without good antennas the range will be probably less than 10 meters which renders the project almost useless. With the antennas the initial tests were successful at transmitting at 15 meters indoors (3 concrete walls in between) which is a great result.

I guess outdoors the range can easily reach at least 60 meters at line of sight, probably more. I will post an update when I test it. And if this is not enough the range can be further extended by increasing the voltage of the transmitter from 5 volts to the maximum the transmitter can accept. On mine it is 12 volts (Please check your transmitter max voltage)

Parts List(for a 2-3 channel transmitter):

1. PS2 Game Joystick Module

2. 315Mhz/433Mhz transmitter receiver pair

3. Antennas

4. Arduino Nano v3  – 2pcs

5. Power bank for transmitter power (Optional)

Total cost is under 10$ without the power bank

For the transmission I will be using the RadioHead library and more specifically their RH_ASK Class. In order for the code to compile you will need to download the library from:  http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.61.zip

If you like how RadioHead works for you, please consider donating to the author at http://www.airspayce.com/ via the Donate button

The  first thing you should do after installing the RadioHead library is to force it to use Timer2 otherwise it will conflict with the Servo library and the code will not compile. To instruct RadioHead to use Timer2 you need to go to the place you installed the library and find the file named RH_ASK.cpp  Edit the file with your favorite editor and find the line // #define RH_ASK_ARDUINO_USE_TIMER2. Uncomment the line, save the file and you are done. If you don’t do this you will get an error during compilation of the receiver code saying  something about `__vector_11′ being already used.

Building the transmitter:

Parts:

  1. PS2 Game Joystick Module
  2. 433Mhz transmitter
  3. Arduino Nano
  4. Antenna (optional but highly recommended)

The parts should be connected in the following manner:

Transmitter data pin should be connected to pin 12 on the Arduino Nano. Transmitter Vcc to the 5v on the Arduino and the transmitter GND to Arduino GND.

The PS2 Joystick should be connected ass follows: GND on the Joystick to the GND on the arduino, +5V on the joystick to the 5V on the arduino, VRx should be connected to A0 on the arduino, VRy should be connected to A1 and the SW on the joystick should be connected to D2 on the Arduino. Basically that is how simple it is.

//Transmitter code

#include
#include // Not actually used but needed to compile

RH_ASK driver(1000, 11, 12, 10); // bps,rx,tx

int xPin = A1;
int yPin = A0;
int buttonPin = 2;

int xPosition = 0;
int yPosition = 0;
int buttonState = 0;

void setup()
{
Serial.begin(115200); // Debugging only
if (!driver.init())
Serial.println("init failed");
}
void loop()
{
// Since my joysticks are really not precise we can encode their values at 256 possibly less
xPosition = analogRead(xPin);
xPosition = map(xPosition, 0, 1023, 0, 255);
yPosition = analogRead(yPin);
yPosition = map(yPosition, 0, 1023, 0, 255);
buttonState = digitalRead(buttonPin);

//Put the values in the array, 8 bits per input
uint8_t values[3];
values[0]=(uint8_t) xPosition;
values[1]=(uint8_t) yPosition;
values[2]=(uint8_t) buttonState;

Serial.print(xPosition);
Serial.print(" : ");
Serial.println(yPosition);
driver.send(values, 3);
driver.waitPacketSent();
delay(2);
}

Building the receiver:

Parts:

  1. 433Mhz transmitter
  2. Arduino Nano
  3. One or two servos (depending on your specific needs)
  4. External 5 volt power supply at least 1A for the servo(s) since they require larger currents
  5. Antenna (optional but highly recommended)

The parts should be connected in the following manner:

Receiver data pin should be connected to pin 11 on the Arduino Nano. Receiver Vcc to the 5v on the Arduino and the Receiver GND to Arduino GND.

Servo signal pin(yellow or white wire) should be connected to D3, servo ground wire(black or brown) should be connected to the Arduino GND and also to the external power supply ground. The servo positive + wire(Red) should be connected to the external power supply +5V.

If you are connecting a second servo connect its signal pin to D9 and its positive and negative terminals just as the first servo

The code is currently set to 1000 bps  so it would have slower speed but better range and thus it is easier to test. Please feel free to increase that to 2000 after successful tests. To avoid headaches please after uploading the code to the transmitter move it to a different USB power supply. I had a lot of issues trying to transmit anything when the transmitter and receiver were both connected to the USB ports on my laptop. Moving the transmitter to an external USB power supply instantly resolved the issues. The button on the receiver is connected to the LED pin D13 but it also seems to be used  by RadioHead for transmission indication. Please change that according your needs

//Receiver code

#include 
#include  // Not actualy used but needed to compile
#include 

Servo servo1;
Servo servo2;
//RH_ASK driver;
 RH_ASK driver(1000, 11, 12, 10); // bps,rx,tx


//Those are used for fine tuning
int SERVO_LOW = 0;
int SERVO_HIGH = 180;
int c1,c2,c3;

// Pin assignments for channels(output to servos)
byte CH1_PIN = 3;
byte CH2_PIN = 9;
byte CH3_PIN = 13;

void setup()
{   
    servo1.attach(CH1_PIN);
    servo2.attach(CH2_PIN);
    pinMode(CH3_PIN, OUTPUT);

    // Debugging only, comment serial stuff when done  
    Serial.begin(115200); 
    if (!driver.init())
         Serial.println("init failed");
}
void loop()
{
    uint8_t buf[12];
    uint8_t buflen = sizeof(buf);
    if (driver.recv(buf, &buflen)) // Non-blocking
    {
        c1 = buf[0];
        c2 = buf[1];
        c3 = buf[2];

        // Remap values to the predefined range
        byte v1 = map(c1, 0, 255, SERVO_LOW, SERVO_HIGH); 
        byte v2 = map(c2, 0, 255, SERVO_LOW, SERVO_HIGH);

        servo1.write(v1);
        servo2.write(v2);

        //Output button state to a led
        digitalWrite(CH3_PIN, c3); 

        //Servo reaction time(adjust delay to your needs)
        delay(35);
     
        Serial.print(v1);
        Serial.print("  ");
        Serial.println(v2);
    }

}

Enjoy your new 2(3) channel arduino remote controller!

Arduino multiple sensor wireless thermometer using 433Mhz/315Mhz RF modules

I always wanted a thermometer displaying the temperature of each room of the house and was thinking of buying a weather station to solve this. The problem was that most weather stations had one remote sensor and I needed at least 3.

I decided to build my own base station capable of displaying the temperature from multiple sensors around the house. I wanted the project to be cheap so I decided to use those 315/433Mhz receiver/transmitter pairs for under a dollar. For the display I chose a 1602 which has the I2C interface so I can interface it with only a few cables and for sensors/base station I chose Arduino nanos.

I was thinking of using the Arduino Wire library for the communication but as I wanted to be able to expand the project with remote power outlets at some later time I just chose to use the RC-Switch Library http://code.google.com/p/rc-switch/

 

The wiring of the modules is really easy, you just connect GND to the Arduino Groud, the VCC to +5V on the Arduino and the DATA to:

  • Remote sensor transmitter module DATA pin to Arduino D10
  • Base station receiver DATA pin to Arduino D2

Since I don’t need the temperature readings to be super precise the only thing I needed for the reading was a cheap 10K thermistor and a 10K resistor

 

sender

Wireless sensor code follows. The code contains code fragments from Arduino Playground http://playground.arduino.cc/ComponentLib/Thermistor2

In order to compile it you will need rc-switch library which you can download at http://code.google.com/p/rc-switch/.

# Remote sensor Arduino code
#include <RCSwitch.h>
#define ThermistorPIN 6 // Analog Pin 6

RCSwitch mySwitch = RCSwitch();
int sensorID = 2; //For the purpose of multiple sensors. Valid values would be 1..9


double ReadTemperature(){

int RawADC = analogRead(ThermistorPIN);
long Resistance; double Temp; // Dual-Purpose variable to save space.
Resistance=10000.0*((1024.0/RawADC) - 1); // Assuming a 10k Thermistor. Calculation is actually: Resistance = (1024 /ADC -1) * BalanceResistor

 Temp = log(Resistance);
 Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
 Temp = Temp - 273.15; // Convert Kelvin to Celsius

 // Uncomment following line for the function to return Fahrenheit instead.
 //Temp = (Temp * 9.0)/ 5.0 + 32.0;
 return Temp;
}

void setup() {
 Serial.begin(9600);
 // Transmitter is connected to Arduino Pin #10 
 mySwitch.enableTransmit(10);
}

void loop() {
 double temp=ReadTemperature();
 Serial.println(temp);
 
 // A simple way of encoding sensor ID and value in one code
 long codetosend = temp*100+(sensorID*100000);
 
 mySwitch.send(codetosend, 24);
 delay(200);
}

The code above is not optimized at all for battery operation since I am powering those “sensors” through usb. If you want to make those more battery friendly there are a lot of useful guides on the internet. Serial prints are also not needed and can be removed. I was only using those for debugging purposes

Base Station

The base station consists of an I2C 1602 LCD Display, Arduino Nano3, 315/433Mhz receiver. Everyone needs to know the local temperature on the base station so again we need the same 10K thermistor connected the same way as in the Remote sensor

In order to compile the Base Station code you will need libraries Wire, LiquidCrystal_I2C and RCSwitch

Base station code follows:

# Base Station Arduino code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RCSwitch.h>

#define I2C_ADDR 0x27 // <<----- Add your address here. Find it from I2C Scanner
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
#define ThermistorPIN 6 // Analog Pin 6

RCSwitch mySwitch = RCSwitch();
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);


double ReadTemperature(){
int RawADC = analogRead(ThermistorPIN);
long Resistance; double Temp; // Dual-Purpose variable to save space.
Resistance=10000.0*((1024.0/RawADC) - 1); // Assuming a 10k Thermistor. Calculation is actually: Resistance = (1024 /ADC -1) * BalanceResistor

 Temp = log(Resistance);
 Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
 Temp = Temp - 273.15; // Convert Kelvin to Celsius

 // Uncomment following line for the function to return Fahrenheit instead.
 //Temp = (Temp * 9.0)/ 5.0 + 32.0;
 return Temp;
}

void setup() {
 delay(600);
 lcd.begin (16,2); // <<----- My LCD is 16x2
 Serial.begin(9600);
 mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin #2

 // Switch on the backlight
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH);
 lcd.home (); // go home
}

#define ThermistorPIN 6 // Analog Pin 6
double temp;
double rc=0;
void loop() {
 double temp=ReadTemperature();
 // End of Line
 Serial.println(temp);
 lcd.setCursor ( 0, 0 );
 lcd.print(temp);
 lcd.print("C");
 rc=0;

 for (int i=0;i<100;i++){
 // TRY TO READ VALUE 100 times!
 if (mySwitch.available()) {
  int value = mySwitch.getReceivedValue();
  if (value == 0) {
  Serial.print("Unknown encoding");
 } else {
 rc = mySwitch.getReceivedValue();
  // Process value from Remote sensor 2 and display reading on the right line1
  if (abs(rc)>=150000 && abs(rc)<250000){
   rc=(rc-200000)/100;
   lcd.setCursor ( 10, 0 );
   lcd.print(rc);
   lcd.print("C");
   }
  // Process value from Remote sensor 3 and display it on the left line 2
  if (abs(rc)>=250000&& abs(rc)<350000){
   rc=(rc-300000)/100;
   lcd.setCursor ( 0, 1 );
   lcd.print(rc);
   lcd.print("C");
  }
 }
 }
 delay(10);
 }
 //Update delay
 delay(2500);
 lcd.clear();
}

The code only manages 1 local and 2 remote sensors but you can add more by just adding the respective code just like the one for sensor 2 &3. Hint:  Don’t forget to set a unique sensor ID in the remote sensor code ;-)

Wiring the Base Station

Display  – we need an I2C display so it only needs 4 wires: GND, VCC, SDA and SCL

Connect GND to ground on the Arduino and VCC to the 5V of the Arduino, SDA to A4 and SCL to A5

Receiver

Connect GND to ground on the Arduino and VCC to the 5V of the Arduino, DATA to D2 on the Arduino

Thermistor

Connect the thermistor and resistor just like on the remote sensor, reading on pin A6

Sourcing the parts:

Resistor, thermistor and cables are widely available in local electronics stores

I2C 1602 Display

Arduino Nano v3

433Mhz Transmitter and Receiver pair

P.S. If you are looking at the code and thinking what are we doing to encode the values and sensor ID in one code and  how do we handle negative values when the code we transmit is always positive?   Well :)  it is not that easy to understand but you can figure it out by looking at the code a bit more. You just need to know that the effective temperature range is from -499.99 to 499.99 by design. E.g. Remote sensors cannot transmit values outside of this range

Done! Enjoy your multi sensor thermometer

I just found those great 433 Mhz antennas for the modules. With those the range of the sensors increases dramatically! Just solder them on the antenna spot and you’re done

Programming an Arduino Pro Mini with another Arduino

Warning: Executing the steps below will re-program both of your Arduinos, so if you have something valuable on the Arduino Nano please be sure to backup first. If you can’t afford to  erase your Nano please don’t follow this instructions

I usually use Arduino nano 3 for all my projects because it is reasonably small and still has a lot of pins, it also uses male headers instead of the female ones that the Uno does, of course this is not breadboard friendly but I kind of like it more.

But there comes a time when you want your projects to be even smaller and if possible a lot cheaper.

For that purpose I recently bought a couple of arduino pro minis(5 volts version). They also have the Atmega328P chip as the Nano and the price is much cheaper but don’t have the micro usb port and there lies the trouble… How can I program this?

arduinoProMini

I searched the net for possible solutions and found a lot which ranged from using external USB to serial board to … well using an arduino uno and removing its chip while programming, but all I had was an Arduino Nano R3!

Arduino Nano 3

Ordering a usb to ttl serial adapter was not an option because of the long delivery time so I had to do something…

I have done a lot of thinking and here is what I came up with…

What will happen if I just connect GND to GND, 5V on the Nano to the VCC of the PRO MINI, RX0 on the Nano with the RX1 on the Pro Mini, the RST on the Nano with the RST on the Pro mini and the TX1 on the Nano with the TX0 on the Pro Mini? After all they have the same chip ATmega328P

The only thing that can happen is an error while programming because when starting the programming the Arduino IDE will ask the microcontroller stuff and both chips will answer

Ok then… let’s make the Pro Mini unable to answer(no, I’m not going to break stuff :)). The thing we will do is disconnect the cable that goes from TX1 to TX0. And voila! You can program your Arduino Pro Mini with the Arduino Nano!

Go to Arduino IDE and select Arduino Nano /w ATmega 328 as your board and upload the sketch. Doing so will really be programming both Arduinos but who cares!

The same hack should work with other Arduinos as well but it always has to be the same chip running on the same frequency and the same voltage. Do not try it if these three conditions are not met!

Enjoy!

Connect the pro mini and the nano as follows:

arduinos