Wireless control of 2 stepper motors

Arduino: wireless contol of 2 stepper motors from Bajdi on Vimeo.

A month ago I wrote a sketch to control 2 little stepper motors with an analog joystick. After getting the Nrf24L01 modules to work last week I wanted to connect the joystick to one Arduino and the stepper motors to another Arduino. It was easier then I thought, I just put the 2 analog values from the joystick in an array. Then we can sent that array to the other Arduino and that’s about it :) I connected the little 28YBJ-48 stepper motors to my Arduino Mega 2560 and the joystick to my Uno. As you can see in the video I’m using 2 different Nrf24L01 modules, the one connected to the Mega 2560 has a preamp and amp the one connected to the Uno is the small version with integrated antenna. I have 2 of each of these modules, but I seemed to have blown one up. I mistakenly connected 5V to one of the small modules and it’s dead :( Already ordered a couple of new ones on Ebay :) Luckily it was only a small module, I paid 20$ a piece for the big modules with preamp and amp, I’m NOT going to blow those up.
Here is the code I used:
Transmitter code:

 // http://www.bajdi.com
// Nrf24L01 connected to Arduino Uno
// Nrf24L01 connection details http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
// Transmit analog values from joystick to the receiver

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

int joystick[2];

void setup(){

  Serial.begin(9600);
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"clie1");
  Mirf.payload = sizeof(joystick);
  Mirf.config();
}

void loop(){
  joystick[0] = analogRead(A0);
  joystick[1] = analogRead(A1);
  Serial.println(joystick[0]);
  Serial.println(joystick[1]);

  Mirf.setTADDR((byte *)"serv1");

  Mirf.send((byte *) &joystick);

  while(Mirf.isSending()){
  }
}

Receiver code:

// http://www.bajdi.com
// Nrf24L01 connected to Arduino Mega 2560
// Nrf24L01 connection details http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
// Receives analog values (joystick) from transmitter and moves stepper motors left/right forward/backward

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include <Stepper.h>

const int stepsPerRevolution = 64;

Stepper small_stepper(stepsPerRevolution, 8,10,9,11);
Stepper small_stepper2(stepsPerRevolution, 4,6,5,7);

int joystick[2];

void setup(){

  small_stepper.setSpeed(250);    // set first stepper speed
  small_stepper2.setSpeed(250);   // set second stepper speed
  Mirf.cePin = 48;             //ce pin on Mega 2560
  Mirf.csnPin = 49;            //csn pin on Mega 2560
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"serv1");
  Mirf.payload = sizeof(joystick);
  Mirf.config();
}

void loop(){

  while(!Mirf.dataReady()){
  }
  Mirf.getData((byte *) &joystick);

  if (joystick[0] < 490) {
    small_stepper.step(1);
  }   // step forward
  if (joystick[0] > 540) {
    small_stepper.step(-1);
  }  // step backward

  if (joystick[1] < 490) {
    small_stepper2.step(1);
  } // step left
  if (joystick[1] > 540) {
    small_stepper2.step(-1);
  } // step right
}

Playing with Nrf24L01 modules

Nrf24L01

Nrf24L01

I recently bought 4 Nrf24L01 modules, 2 small modules with internal antenna and 2 bigger ones with a preamp, amp and external antenna. You can find the small modules for less then 5$ a piece on Ebay. It’s the cheapest way make a wireless connection between 2 Arduino’s. These modules are based one the Nordic Semiconductor nRF24L01+ chip and use the SPI bus and 2 extra pins, you can find more information and how to connect them here. I found 2 libraries for these chips, the Mirf library on the Arduino playground and Maniacbugs RF24 library. I had some trouble getting these things to work, I searched the Arduino forum and it seems that I wasn’t the only one having issues with these modules and an Arduino Mega 2560. You can read about it here. After a lot of head scratching I got all 4 of the modules to work. I then tried to make some own sketches using the RF24 library and failed miserably. I have lot to learn when it comes to coding :(
I then tried out the Mirf library and had a bit more success. I managed to write 2 sketches (transmitter and receiver) that sent the analog value from one Arduino to the other. I think this is the minimum code you need to get them to work. Well it’s a start… I hope to use these modules to remote control a “robot”.
Here are the sketches:
The following sketch goes in to the transmitter. (I used my Arduino Mega 2560 with a potentiometer connected to analog pin A0)

// http://www.bajdi.com
// Nrf24L01 connected to Mega 2560
// Nrf24L01 connection details http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
// Transmit analog value from pin A0 to the receiver

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

int rate;

void setup(){

  Serial.begin(9600);
  Mirf.cePin = 48;             //ce pin on Mega 2560
  Mirf.csnPin = 49;            //csn pin on Mega 2560
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"clie1");
  Mirf.payload = sizeof(rate);
  Mirf.config();
}

void loop(){
  rate = analogRead(A0);

  Mirf.setTADDR((byte *)"serv1");

  Mirf.send((byte *) &rate);

  while(Mirf.isSending()){
  }
}

The following sketch goes in to the receiver Arduino. (from this Arduino we can read the analog value through the serial monitor)

// http://www.bajdi.com
// Nrf24L01 connected to Arduino Uno
// Nrf24L01 connection details http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
// Receives analog value from transmitter and display it on serial monitor

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

int rate;

void setup(){

  Serial.begin(9600);

  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"serv1");
  Mirf.payload = sizeof(rate);
  Mirf.config();
}

void loop(){

  while(!Mirf.dataReady()){
  }
  Mirf.getData((byte *) &rate);

  Serial.println(rate);
  delay(100);
}

With some small changes to the above sketch we can use the value read from the potentiometer (rate) and map it to a value between 0 and 255 to dim a led (analogwrite function).

// http://www.bajdi.com
// Nrf24L01 connected to Arduino Uno
// Nrf24L01 connection details http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
// Receives analog value from transmitter and maps it to a PWM range (0-255) to dim a led

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

int rate;
int ledValue;

const int led = 3;

void setup(){

  Serial.begin(9600);
  pinMode(led, OUTPUT);
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"serv1");
  Mirf.payload = sizeof(rate);
  Mirf.config();
}

void loop(){

  while(!Mirf.dataReady()){
  }
  Mirf.getData((byte *) &rate);
  ledValue = (map( rate, 0, 1024, 0, 255 ) );
  analogWrite(led, ledValue);
  Serial.println(ledValue);
  delay(10);
}

RGB led color mixing

Arduino RGB led color mxing from Bajdi on Vimeo.

The above video is what you get when you connect 3 RGB leds to an Arduino Mega 2560. I covered them with the diffusion cover from my Nikon flash to get a better light diffusion. RGB leds are fun things, you can make some cool visual effects with a couple of these leds. I got my inspiration from here.

DHT22 datalogging

Datalogging dht22 to SD card

By connecting a DHT22 temperature and humidity sensor, a DS1307 RTC module and an SD card module to the Arduino Mega 2560 we can make a data logging system. The DHT22 sensor measures the temperature, the DS1307 gives us the date and time and this data is then written to the SD card over the SPI bus. The values from the DHT22 sensor and the DS1307 are comma separated so you can easily import the data in a spreadsheet. Was straightforward to get to work. The data is written every 3 seconds to the SD card, I just used the “delay” function. Should use the time from the DS1307 the next time. I tried adding an ethernet module to the mix but I can’t get the SD card and the ethernet module to work together on the Mega 2560, although separately they work.
The sketch:

/*

http://www.bajdi.com

  SD card datalogger for Arduino Mega (this sketch will ONLY work with Arduino Mega) 

 This example shows how to log data from a DHT22, to an SD card using the SD library.
 Time stamp is taken from a DS1307.

  * SD card attached to SPI bus as follows:
 ** MOSI - pin 51
 ** MISO - pin 50
 ** CLK - pin 52
 ** CS - pin 53

 */

#include <Wire.h>
#include "RTClib.h"
#include <dht.h>
#include <SD.h>
dht DHT;

RTC_DS1307 RTC;

#define DHTTYPE DHT22 // Sensor type
#define DHT22_PIN 2   // DHT22 signal on pin 2

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 53;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  RTC.adjust(DateTime(__DATE__, __TIME__));
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(53, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  DateTime now = RTC.now();

  int chk = DHT.read22(DHT22_PIN);

  File dataFile = SD.open("datalog.csv", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.print(now.day(), DEC);
    dataFile.print('/');
    dataFile.print(now.month(), DEC);
    dataFile.print('/');
    dataFile.print(now.year(), DEC);
    dataFile.print(" , ");
    dataFile.print(now.hour(), DEC);
    dataFile.print(':');
    dataFile.print(now.minute(), DEC);
    dataFile.print(" , ");
    dataFile.println((float)DHT.temperature);
    dataFile.close();
    // print to the serial port too:
    Serial.println(DHT.temperature);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.csv");
  }
  delay(3000);
}

Flamingo EDA ethernet module

Flamingo EDA ethernet and IDC shield

Flamingo EDA ethernet and IDC shield

I’m working on a sketch that includes my Flamingo EDA ethernet module. The module I have is not a shield that you can plug on an Arduino but a separate board with the Wiznet W5100 chip on. I bought it together with the IDC shield, you can plug this shield on an Arduino Duemilanove/Uno and then connect both of the SPI connectors. I got it working on my Uno but this time I want to connect it to the Arduino Mega 2560. The IDC shield does not work on the Mega, because the Mega 2560 has a different location of the SPI pins. So I needed to find out which pin of the ethernet board is which pin of the SPI bus. The Flamingo EDA ethernet shield has 3 connectors, they are labelled INT, SPI and RESET. You only need to connect the SPI connector. I don’t know what the other 2 connectors are good for, maybe to update the firmware? I couldn’t find the pin layout online so I did some testing with my multimeter and found out how to connect it to my Mega. You can find the location of the SPI pins of the Arduino Mega 2560 on the official Arduino Mega 2560 page.

Flamingo EDA ethernet module

Flamingo EDA ethernet module

I edited the official photo of the Mega 2560 to include the SPI pin layout for easy reference.

Arduino Mega 2560

Arduino Mega 2560