Bajdi electronics

Hobby electronics website

Browse: Page 28

Arduino remote control

By Bajdi on May 4, 2012

DIY remote control

DIY remote control

I built myself a remote control, Arduino based of course. I needed something that was more practical to use then just an Arduino Uno with various parts connected to it. My old remote control consisted of an Arduino Duemilanove with a joystick, wireless nRF24L01 module, Lipo battery and LCD attached. I had to hold all these parts in my hands to play with my Rover 5. My new remote control will be a bit more practical to use.

I bought a joystick shield that fits on top of the Arduino. I then measured it and started drawing 2 plates in Autocad. I found a local company that has a laser cutter and they cut me 2 acrylic plates, not cheap but worth it. The 4 x 20 I2C LCD sits in the top, very handy for debugging while your robot is driving around. I made a PCB with a 3,3V regulator and female header pins to put the wireless nRF24L01 module in, the nRF24L01 module needs 3,3V. The smaller modules can be powered from the 3,3V regulator on the Arduino but the bigger modules with amp and preamp need a separate regulator. The connection from the joystick shield to the nRF24L01 module and the I2C LCD I made by soldering some thin wires directly on top of the shield.

Power comes from a small 2 cell 500mAh Lipo battery. I soldered a connector that distributes the power from the battery to the Arduino and 3,3V regulator. The Arduino Uno is mounted on 10mm brass spacers, and between the 2 plates there are 4 30mm spacers. The reason I didn’t use my Duemilanove is that these only have 3 mounting holes, so you can’t properly mount them. Which is necessary with a joystick shield on top of it, as you will be putting a downward force on it. Thankfully I had an Uno (Chinese clone) laying around. I’m quite happy with the result 🙂

Posted in Arduino | Tagged nRF24L01 | 5 Responses

Syncing DS1307 RTC with timeserver

By Bajdi on May 1, 2012

Arduino data logging webserver ds1307 and lcd

Arduino data logging webserver ds1307 and lcd

My last data logging sketch was missing one feature to make it complete. Since I use a DS1307 RTC which is not very accurate, it loses a couple of seconds a day, I wanted to sync the time with a timeserver.

Thankfully some smart people on the Arduino site have already made a library and example sketch to do exactly that. The sketch uses the UDP protocol to sync with a NTP timeserver. So this was just a matter of integrating the example sketch to my data logging sketch. While I was at it I also connected my new 4×20 I2C LCD to my Arduino and wrote some code to sent the values of the temperature sensors and RTC clock to the LCD. So now I have a fully working data logging sketch which keeps accurate time 🙂

All the data is written to a SD card once every 10 seconds, and I can look up the data on a little webserver. Pretty cool. The sketch is nothing more then a combination of the various example sketches that come with the 9 libraries used for this sketch.
The sketch is quite big, almost maxing out the memory of the ATmega328.

Here is the complete sketch:

/*
 http://www.bajdi.com
 SD card temperature logger and webserver with DS1307 RTC.
 
 This sketch shows how to log data from a DHT22 and DS18B20 sensor to an SD card using the SD library.
 The data from the sensors is updated every 10 seconds and written to the SD card in a CSV file.
 Time stamp is taken from a DS1307 RTC. The data of the DHT22, DS18B20 and RTC is also available on a webserver.
 The time of the DS1307 RTC is synced with a timeserver once a day. (DS1307 is not accurate over a long time.) 
 */

#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include "RTClib.h"
#include <dht.h>
#include <SD.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Udp.h>

unsigned int localPort = 8888;             // local port to listen for UDP packets
byte timeServer[] = {81, 95, 126, 170};    // be.pool.ntp.org NTP server  
const int NTP_PACKET_SIZE= 48;             // NTP time stamp is in the first 48 bytes of the message
byte pb[NTP_PACKET_SIZE];                  // buffer to hold incoming and outgoing packets

LiquidCrystal_I2C lcd(0x27,20,4);

const int ONE_WIRE_BUS = 3;                // signal pin of DS18B20 connected to pin 3
OneWire ourWire(ONE_WIRE_BUS);
DallasTemperature sensors(&ourWire);

dht DHT;

RTC_DS1307 RTC;

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

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 
  192,168,1, 10 };

int lastTime = -1;
int lastTime2 = -1;

float temp;            // float for temperature value from DS18B20

char filename[] = "00000000.CSV";

Server server(80);

const int chipSelect = 4;      // CS for SD card

void setup()
{
  Serial.begin(9600);
  lcd.init(); // initialize the lcd
  lcd.backlight();
  Ethernet.begin(mac, ip);
  server.begin();
  Wire.begin();
  sensors.begin();            // for DS18B20 sensor
  delay(200);
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  delay(100);
  Serial.print("Initializing SD card...");
  pinMode(10, 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();                              // get time from RTC

  int time = now.second();
  if (abs(time - lastTime) > 10)
  {
    int chk = DHT.read22(DHT22_PIN);                       // get data from DHT22
    sensors.requestTemperatures();                         // get data from DS18B20
    temp = sensors.getTempCByIndex(0);                  
 
    getFilename(filename);
    File dataFile = SD.open(filename, 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.print((float)DHT.temperature);
      dataFile.print(" , ");
      dataFile.println((float)temp);
      dataFile.close();
    }  
    // if the file isn't open, pop up an error:
    else {
      Serial.print("error opening ");
      Serial.println(filename);
    }
    lastTime = time;
  }

  Client client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          client.print(now.day(), DEC);
          client.print('/');
          client.print(now.month(), DEC);
          client.print('/');
          client.print(now.year(), DEC);
          client.print(' ');
          client.print(now.hour(), DEC);
          client.print(':');
          client.print(now.minute(), DEC);
          client.println("<br />");
          client.print("Arduino powered webserver");
          client.println("<br />");
          client.print("Serving temperature and humidity values from a DHT22 and DS18B20 sensor");
          client.println("<br />");
          client.print("Inside temperature (oC): ");
          client.print(DHT.temperature);
          client.println("<br />");
          client.print("Humidity (%): ");
          client.print(DHT.humidity);
          client.println("<br />"); 
          client.print("Outside temperature (oC): ");
          client.print(temp); 
          client.println("<br />"); 

          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }

  int time2 = now.day();
  if (abs(time2 - lastTime2) > 1)
  {
    Udp.begin(localPort);
    delay(250);
    // send an NTP packet to a time server
    sendNTPpacket(timeServer);

    // wait to see if a reply is available
    delay(1000);

    if ( Udp.available() ) {
      // read the packet into the buffer

      Udp.readPacket(pb, NTP_PACKET_SIZE);

      // NTP contains four timestamps with an integer part and a fraction part
      // we only use the integer part here
      unsigned long t1, t2, t3, t4;
      t1 = t2 = t3 = t4 = 0;
      for (int i=0; i< 4; i++)
      {
        t1 = t1 << 8 | pb[16+i];      
        t2 = t2 << 8 | pb[24+i];      
        t3 = t3 << 8 | pb[32+i];      
        t4 = t4 << 8 | pb[40+i];
      }

      // part of the fractional part
      // could be 4 bytes but this is more precise than the 1307 RTC
      // which has a precision of ONE second
      // in fact one byte is sufficient for 1307
      float f1,f2,f3,f4;
      f1 = ((long)pb[20] * 256 + pb[21]) / 65536.0;      
      f2 = ((long)pb[28] * 256 + pb[29]) / 65536.0;      
      f3 = ((long)pb[36] * 256 + pb[37]) / 65536.0;      
      f4 = ((long)pb[44] * 256 + pb[45]) / 65536.0;

      const unsigned long seventyYears = 2208988800UL;
      t1 -= seventyYears;
      t2 -= seventyYears;
      t3 -= seventyYears;
      t4 -= seventyYears;

      // Adjust timezone and DST... in my case substract 4 hours for Chile Time
      // or work in UTC?
      t4 += (2 * 3600L);     // Notice the L for long calculations!!
      t4 += 1;               // adjust the delay(1000) at begin of loop!
      if (f4 > 0.4) t4++;    // adjust fractional part, see above
      RTC.adjust(DateTime(t4));

      Serial.println("RTC synced");
    }
    lastTime2 = time2;
  }


  lcd.setCursor(0, 0);
  lcd.print(now.year(), DEC);
  lcd.print('/');
  if (now.month() < 10)
    lcd.print("0");
  lcd.print(now.month(), DEC);
  lcd.print('/');
  if (now.day() < 10)
    lcd.print("0");
  lcd.print(now.day(), DEC);
  lcd.setCursor(11, 0);
  if (now.hour() < 10)
    lcd.print("0");
  lcd.print(now.hour(), DEC);
  lcd.print(':');
  if (now.minute() < 10)
    lcd.print("0");
  lcd.print(now.minute(), DEC);
  lcd.print(':');
  if (now.second() < 10)
    lcd.print("0");
  lcd.print(now.second(), DEC);
  lcd.setCursor(0, 1);
  lcd.print("Indoor temp:");
  lcd.print((float)DHT.temperature, 1);
  lcd.setCursor(3, 2);
  lcd.print("humidity:");
  lcd.print((float)DHT.humidity,1);
  lcd.setCursor(0, 3);
  lcd.print("Outdoor temp:");
  lcd.print(temp);

}

void getFilename(char *filename) {
  DateTime now = RTC.now(); 
  int year = now.year(); 
  int month = now.month(); 
  int day = now.day();
  filename[0] = '2';
  filename[1] = '0';
  filename[2] = (year-2000)/10 + '0';
  filename[3] = year%10 + '0';
  filename[4] = month/10 + '0';
  filename[5] = month%10 + '0';
  filename[6] = day/10 + '0';
  filename[7] = day%10 + '0';
  filename[8] = '.';
  filename[9] = 'C';
  filename[10] = 'S';
  filename[11] = 'V';
  return;
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(byte *address)
{
  // set all bytes in the buffer to 0
  memset(pb, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  pb[0] = 0b11100011;   // LI, Version, Mode
  pb[1] = 0;     // Stratum, or type of clock
  pb[2] = 6;     // Polling Interval
  pb[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  pb[12]  = 49;
  pb[13]  = 0x4E;
  pb[14]  = 49;
  pb[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:

  Udp.sendPacket( pb,NTP_PACKET_SIZE,  address, 123); //NTP requests are to port 123
}

Posted in Arduino sketches | Tagged DS1307 | 27 Responses

Building a line following robot

By Bajdi on April 30, 2012

Volga the line following robot

Volga the line following robot

I’ve started a new project, another “robot” and I’m going to name it Volga. When I was drawing a track in Autocad for the robot to follow I thought it looked like a river 🙂 And it’s made up of cheap parts just like those Russian cars. This will be a simple line following robot, and a cheap one. I already had 95% of the parts needed to make a line following robot, and almost all of them come from Ebay. So it only took a couple of hours to built it to the state it is in now.

For the chassis I used a plastic box that I had lying around. The motors are 2 continuous rotation servos stuck to the chassis with double sided tape, I screwed 2 cheap 76mm wheels from Ebay to the servo horns. Also on Ebay I found a cheap castor wheel. I made up my own line following sensor, it consists of 3 TCRT5000 sensors soldered to a pcb. The pcb is mounted to the front of the chassis with 2 brass spacers.

The brain of this robot is an Arduino Nano. Power comes from a 2 cell Lipo battery, the battery is connected to the Vin pin of the Nano and the input of a 3 Amp UBEC voltage regulator. The UBEC gives 5V to the 2 continuous rotation servos. I first experimented with a LM7805 linear voltage regulator. But it became so hot after only letting the servos run for 5 min I decided to use the UBEC. I’ve hooked up an IR receiver to the Nano so I can control it with a small remote control, which is always handy. I’ve not coded the line following capability yet. I first wanted to test the basic functions, motors forward, backward, left and right. At the moment I only have a basic sketch to remote control the robot through the IR receiver. It’s a start 🙂

The Arduino Nano is sitting on a breadboard for now, I’m planning on building an “undershield” for it. I recently stumbled on the website of Rocket brand studios, they sell a small pcb where you can put an Arduino Nano on. I’ll make up something similar but I’m waiting for some female header pins. This shield will make it a lot easier to connect stuff to the Arduino Nano without using a breadboard.

Posted in Line following robot | Tagged robot, TCRT5000 | Leave a response

« PreviousNext »

Recent Posts

  • 3D Printer extruders
  • Mearm forked
  • Arduino time lapse – camera pan device
  • Bought a 199$* Prusa I3 3D printer
  • Simple DIY lab power supply
  • Bajduino
    • Bajduino 1284
    • Bajduino 328
  • Stepper robot arm

Recent Comments

  1. 200+ Arduino Projects List For Final Year Students - He Loves Math on Obstacle avoiding robot made from cheap parts
  2. MP3 Alarm Clock: Crafting Customized wake-Up tunes with Arduino on Arduino MP3 alarm clock
  3. Bas on L9110 H-bridge module
  4. Victor on L9110 H-bridge module
  5. WAQAR AHMED on Dimming led with IR remote control

Archives

  • June 2016
  • August 2015
  • May 2015
  • January 2015
  • December 2014
  • November 2014
  • May 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • September 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011

Categories

  • 3D printing
  • Arduino
  • Arduino sketches
  • Bajdupod 996R
  • Bajdupod 9G
  • Bob the biped
  • Buying parts
  • Dagu Rover 5
  • Dagu service droid
  • Gentoo
  • Insectbot
  • Line following robot
  • Raspberry Pi
  • Self balancing bot
  • Bajduino
    • Bajduino 1284
    • Bajduino 328
  • Stepper robot arm

Copyright © 2026 Bajdi electronics.

Powered by WordPress and Hybrid by Bajdi.