Showing posts with label arduino. Show all posts
Showing posts with label arduino. Show all posts

Saturday, 23 November 2013

Arduino - Talking plant, with Twitter (how to tweet data with Arduino)

After I finished the first test with the Ethernet shield and serving your own page from Arduino (see post here) I said, ok, but if I don't have my own static IP address!?!? Most of us don't have a static IP address at home. Yeah it was fun with the other one to play in a LAN or use the university network to get an own IP, but at home this device renders useless. I tried with other social networks or email providers but it looks like Facebook, Yahoo mail and Gmail have quite some problems talking with Arduino and Arduino has some problems talking with them, the only one available remained Twitter.
Having as starting point http://arduino-tweet.appspot.com/ I modified my previous code to this one:


#include <SPI.h> // needed in Arduino 0019 or later
#include <Ethernet.h>
#include <Twitter.h>

// The includion of EthernetDNS is not needed in Arduino IDE 1.0 or later.
// Please uncomment below in Arduino IDE 0022 or earlier.
//#include <EthernetDNS.h>

// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// If you don't specify the IP address, DHCP is used(only in Arduino 1.0 or later).
//byte ip[] = { 192, 168, 9, 122 }; // 192.168.9.122

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("please put here your token");

// Message to post - just to initialize the variable
char msg[] = "Hello, World! I'm Arduino!";

void setup()
{
  delay(10000);
  Serial.begin(9600);
    // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  Serial.println("connecting ...");
  if (twitter.post(msg)) {
    // Specify &Serial to output received response to Serial.
    // If no output is required, you can just omit the argument, e.g.
    // int status = twitter.wait();
    int status = twitter.wait(&Serial);
    if (status == 200) {
   
      Serial.println("OK.");
   
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
 
  } else {
    Serial.println("connection failed.");
  }
}

//Temperaturmessung
//*
int temp = 1;
int oldtemp = 1;
int val;

void loop()
{
  delay(30000);
  val = analogRead(0);

  if (val > 40) { temp = 1; }

  if (val <20 ) { temp = 0; }

  if (oldtemp != temp) {
    oldtemp = temp;
    if (temp == 1) {
      //Serial.println("FEUER!");
      sendTwitterUpdate("Im Gewächshaus brennt es!");
    }
    else {
      //Serial.println("Kalt!");
      sendTwitterUpdate("Es ist zu kalt für die Pflanzen!");
    }
  }

  fetchTwitterUpdate();
}


Now you can get more creative and do more out of it.

Arduino - Talking plant, with HTTP server (or how to see sensor data via internet)


One of the small assignments used for learning Arduino was the classical "talking plant". Actually was more of a build own humidity sensor, sensor reading and sending the data to the Ethernet shield and also use LED lights to display the status of the soil moisture. 

What?
First step is to build a sensor, very simple! Of course you can buy a humidity sensor, no one says not to do so, but makes more fun to built your own, cheaper and simpler.
After the sensor is build all you have to do is just to read the values and then use 3 LED (red, yellow, green) to visually display the soil moisture and at the same time send the values to the Ethernet shield so you can check the humidity of your precious plant over the internet.
Of course you can get more creative than this once you have the data, but I wasn't in the mood to invest money in more cooler ideas. I kept them for my mood lights.

How to build the soil moisture sensor
Actually this is the simplest part. You can use two nails, two thick wires or basically anything that is allowing electricity to pass. The trick is to pick a material that does not get rusty or oxides to quick, also must have a small electric resistance because we are talking here about very small values ... 5V and less than 1A. 
I used two fine steel nails about 5cm long with a 3mm distance between. The nails were fixed on a plastic base 5mm high (to keep the distance between the nails), you can use any material that is resistant to electricity (does not allow electricity to pass). Having a 5cm nail minus 5mm plastic base I remained with a 4.5cm for each nail as the sensing surface.
Note: the nails must be parallel with each other. 
Soldering a wire on each nail head is the only "hard part" of this sensor.

How it works
You need just to "stick" the sensor in the flower pot (you don't want to damage the roots of your precious plant so be careful where you stick it) connect it to the Arduino board like you will do with any other simple sensor (e.g. photoresistor see how to connect a photoresistor)
Unfortunately I have no drawing for this project but the wiring is not so hard. Actually you can get it only by reading the code.
Next step is to connect the 3 LED lights and then calibrate your sensor (see code). The values will differ from one soil type to the other ( depending on the pH value).
Plug your Ethernet shield, use your network values and have fun! (see in the code where)

The code
The code is well commented but if you have questions just ask :)

//#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>

// Ethernet shield attached to pins 10, 11, 12, 13
//analog sensor
int sensorPin = 0;     // 1st sensor is connected to a0
int sensorReading;     // the analog reading from the analog port

//status LEDs
int LEDred =7;              
int LEDyellow =8;  
int LEDgreen =9;

//threshold values - calibrate sensor
int RED = 200;
int GREEN = 500;

//string that holds the status
String Status ="";

//Server part

//define mac address for ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
//define ip for ethernet shield
byte ip[] = { 192, 168, 1, 2 };           // ip in lan
//gateway - router ip address and mask
byte gateway[] = { 192, 168, 1, 20 };            // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                   //subnet mask


// Initialize the server library and port (port 80 is default for HTTP)
Server server(80);                                      //server port


//byte sampledata=50;

void setup(void) {
  pinMode(LEDred, OUTPUT);  //set LED1 pin to output mode
  pinMode(LEDyellow, OUTPUT);  //set LED2 pin to output mode
  pinMode(LEDgreen, OUTPUT);  //set LED3 pin to output mode

  //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();

  //send debugging information via the Serial monitor
  Serial.begin(9600);
}

void HTTPserv () {
// listen for incoming clients
  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 you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        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();
 
    //---------------HTML----------------------------
 //set background color
          client.print("<body style=background-color:yellow>");
          //send first heading
          client.println("<font color='red'><h1>Soil humidity</font></h1>");
          client.println("<hr />");
          client.println("<hr />");
          client.println("<br />");
          client.println("<br />");
 //drawing simple table
          client.println("<font color='black'>Simple table: </font>");
          client.println("<br />");
          client.print("<table border=1><tr><td>Humidity</td>");
 client.print("<td>");
 client.print(sensorReading);
 client.print("</td></tr>");
          client.println("<tr>");
 client.print("<td>Status</td><td>");
 client.print(Status);
 client.print("</td></tr></table>");
          client.println("<br />");
          client.println("<hr />");
 //text variant
          client.println("<hr>");
          client.print("Humidity ");
          client.print(" = ");
          client.print(sensorReading);
          client.println("<br />");
          client.print("Status ");
          client.print(" = ");
          client.print(Status);
          client.println("<br />");
          client.println("<hr>");
          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();
  }
}

void loop(void) {

  digitalWrite(LEDred,LOW); //initial state
  digitalWrite(LEDyellow,LOW); //initial state
  digitalWrite(LEDgreen,LOW); //initial state

  sensorReading = analogRead(sensorPin);

  Serial.println(sensorReading);

  if (sensorReading <= RED) {
   digitalWrite(LEDred,HIGH);
   digitalWrite(LEDyellow,LOW);
   digitalWrite(LEDgreen,LOW);
   Status = "needs urgent attention";
   HTTPserv () ;
 }
 else if (sensorReading > RED && sensorReading < GREEN ) {
   digitalWrite(LEDred,LOW);
   digitalWrite(LEDyellow,HIGH);
   digitalWrite(LEDgreen,LOW);
   Status = "needs attention";
   HTTPserv () ;
 }
 else if (sensorReading >= GREEN ) {
   digitalWrite(LEDred,LOW);
   digitalWrite(LEDyellow,LOW);
   digitalWrite(LEDgreen,HIGH);
   Status = "needs no attention";
 }
 else {
   digitalWrite(LEDred,LOW);
  digitalWrite(LEDyellow,LOW);
  digitalWrite(LEDgreen,LOW);
  Status = "";
  HTTPserv () ;
 }
 delay(1000);
}


Tuesday, 22 January 2013

Speed measurement with Arduino (2)


To continue my first post on speed measurement I will show how I made the arduino part more "interesting" and connected it to flash and as3.

At the end of the post I will attach the files for download.

For connecting arduino with flash I used TinkerProxy, has instructions on how to use it so I will not get into details. 
The flash file will receive the speed value and will capture a picture from the webcam. (Note, for my project I used a webcam to take pictures of the objects that passing). Also it adds to the picture the time stamp and the speed. (processing the image at the runtime). The picture is then saved to the server with a php script.

You can get creative and set a certain threshold :)

AS3 script:

//File downloaded from www.riacodes.com
// Modified by Claudiu Cristian on 28.11.2011
import flash.display.Bitmap;
import flash.display.BitmapData;
import com.adobe.images.JPGEncoder;
import flash.net.FileReference;
import com.SerialPort;
var finalSpeed:Number = 0;
var cam:Camera = Camera.getCamera();
var video:Video = new Video(320,240);
var phpPath:String;
var sendReq:URLRequest;
/*
Connecting with arduino
*/
//Character that delineates the end of a message received from the Arduino
const EOL_DELIMITER:String = "\n";
// accumulates data coming from arduino
var sensorData:String = "";
var speed:Number=0;
// connects to arduino board
var arduino:SerialPort = new SerialPort();
arduino.addEventListener(DataEvent.DATA, onArduinoData );
arduino.connect( "127.0.0.1", 5331 );
function onArduinoData( event:DataEvent ):void {
//trace( "onArduinoData", event.data );
// add to sensor data
sensorData +=  event.data;
// if it finds newline the packet of sensor data is done
if (sensorData.indexOf(EOL_DELIMITER) > 0 ) {
// process sensor data
//trace(parseFloat(event.data));
speed = parseFloat(event.data);
computeSpeed();
}
}
function computeSpeed() {
if (isNaN(speed) == false &&  speed % 1 != 0 ) {
finalSpeed = speed * 3.6;
captureImage();
saveImage();
}
else {
finalSpeed=0;
}
trace(roundDecimals(finalSpeed, 2));
sensorData="";
}
function roundDecimals(num:Number, numDecimalPlaces:int):Number {
return Math.round(num * Math.pow(10, numDecimalPlaces) ) / Math.pow(10, numDecimalPlaces);
}
video.attachCamera(cam);
video.x = 20;
video.y = 20;
addChild(video);
var bitmapData:BitmapData = new BitmapData(video.width,video.height);
var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.x = 360;
bitmap.y = 20;
addChild(bitmap);
function captureImage():void
{
bitmapData.draw(video);
//render the text
drawString(bitmapData,fileName1 + roundDecimals(finalSpeed, 2),10,200);
// display the result...
//addChild(Bitmap (bitmapData));
}
var i:Number = 1;
var fileRef:FileReference = new FileReference();

// script taken from http://www.beautifycode.com/webcam-flash-php-upload-to-server
//and modiffied
function saveImage():void
{
var encoder:JPGEncoder = new JPGEncoder(90);
var ba:ByteArray = encoder.encode(bitmapData);
    var sendHeader:URLRequestHeader = new URLRequestHeader("Content-type","application/octet-stream");
phpPath = "http://localhost/saveimg.php"

    sendReq = new URLRequest(phpPath);
    sendReq.requestHeaders.push(sendHeader);
    sendReq.method = URLRequestMethod.POST;
    sendReq.data = ba;

    var sendLoader:URLLoader;
    sendLoader = new URLLoader();
    sendLoader.load(sendReq);
}
function drawString(target:BitmapData,text:String,x:Number,y:Number):void
{
var tf:TextField = new TextField();
tf.width = 300;
tf.text = text;
var myFormat:TextFormat = new TextFormat();
//Giving the format a hex decimal color code
myFormat.color = 0xFF0000;
//Adding some bigger text size
myFormat.size = 12;
//Last text style is to make it bold.
myFormat.bold = true;
//Now the most important thing for the textformat, we need to add it to the myTextField with setTextFormat.
tf.setTextFormat(myFormat);
var bmd:BitmapData = new BitmapData(tf.width,tf.height,true,0x00000000);
bmd.draw(tf);
var mat:Matrix = new Matrix();
mat.translate(x,y);
target.draw(bmd,mat);
bmd.dispose();
}
var my_timer:Timer=new Timer(1000);
my_timer.addEventListener(TimerEvent.TIMER, onTimer);
my_timer.start();
var fileName:String;
var fileName1:String;
var txtDisplay:TextField = new TextField();

//Here we add the new textfield instance to the stage with addchild()
addChild(txtDisplay);

//Here we define some properties for our text field, starting with giving it some text to contain.
//A width, x and y coordinates.
txtDisplay.x = 20;
txtDisplay.y = 360;

//Here are some great properties to define, first one is to make sure the text is not selectable, then adding a border.
txtDisplay.selectable = false;
txtDisplay.border = true;

//This last property for our textfield is to make it autosize with the text, aligning to the left.
txtDisplay.autoSize = TextFieldAutoSize.LEFT;

function onTimer(e:TimerEvent):void {
var today_date:Date = new Date();
var thismonth:uint = today_date.getMonth();
var today_time;
var currentTime:Date = new Date();
var minutes = currentTime.getMinutes();
var seconds = currentTime.getSeconds();
var hours = currentTime.getHours() * 30 + currentTime.getMinutes() / 2;
var monthArr:Array = new Array('Jan','Feb','March','April','May','June','July','August','September','October','November','December');
fileName = (today_date.getDate()+ " " +monthArr[thismonth]+ " " +today_date.getFullYear()+"  "+currentTime.hours + ":" + currentTime.minutes + ":" + currentTime.seconds);
txtDisplay.text = "Date & Time "+fileName + " | " +"Object speed:" + roundDecimals(finalSpeed, 2) ;
}
PHP script:

<?php
if ( isset ( $GLOBALS["HTTP_RAW_POST_DATA"] )) {
    $uniqueStamp = date(U);
    $filename = $uniqueStamp.".jpg";
    $fp = fopen( $filename,"wb");
    fwrite( $fp, $GLOBALS[ 'HTTP_RAW_POST_DATA' ] );
    fclose( $fp );

    echo "filename=".$filename."&base=".$_SERVER["HTTP_HOST"].dirname($_SERVER["PHP_SELF"]);
}
?>


Flash file  PHP file



Resources
http://code.google.com/p/tinkerit/wiki/TinkerProxy
http://www.riacodes.com/flash/captures-images-from-the-webcam-and-save-them-to-thedesktop/
http://www.beautifycode.com/webcam-flash-php-upload-to-server#php
http://www.ladyada.net/learn/sensors/cds.html




Monday, 6 February 2012

Speed measurement with Arduino

I will begin with my first experience working with Arduino and Arduino IDE. I made a speed detection "device" using 2 laser pointers and 2 LDR sensors connected to an Arduino UNO.

Building the schematics is very easy.


The resistors are used as pull-down resistors and I wired the sensors and put them in a case, to avoid them detecting surrounding light. For each case, a hole was drilled so that the laser beam can light the sensor while the ambient light does not affect the sensor.
The working principle is easy: an object that passes by will "cut" the laser beams, this means the LDR sensor will detect this sudden drop of light intensity. First I defined a threshold value under which the sensor is considered triggered, once the value is under threshold for the first sensor then Arduino waits for the second one to be triggered. During this waiting time it counts the elapsed time between the two events. When the second beam is interrupted, the timer stops and now is just simple math. The distance between the 2 sensors is known, the time between the two events is known, and speed can be computed as speed = distance/time.

Below you can find the Arduino code:

/*
by Claudiu Cristian
*/

unsigned long time1;
int photocellPin_1 = 0;     // 1st sensor is connected to a0
int photocellReading_1;     // the analog reading from the analog port
int photocellPin_2 = 1;     // 2nd sensor is connected to a1
int photocellReading_2;     // the analog reading from the analog port
int threshold = 700;        //value below sensors are trigerd
float Speed;              // declaration of Speed variable
float timing;
unsigned long int calcTimeout = 0; // initialisation of timeout variable

void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);  
}
 
void loop(void) {
  photocellReading_1 = analogRead(photocellPin_1);  //read out values for sensor 1
  photocellReading_2 = analogRead(photocellPin_2);  //read out values for sensor 2  
  // if reading of first sensor is smaller than threshold starts time count and moves to calculation function
  if (photocellReading_1 < threshold) {
   time1 = millis();
   startCalculation();
 }
}

// calculation function
void startCalculation() {
  calcTimeout = millis(); // asign time to timeout variable 
  //we wait for trigger of sensor 2 to start calculation - otherwise timeout
  while (!(photocellReading_2 < threshold)) {
    photocellReading_2 = analogRead(photocellPin_2);  
    if (millis() - calcTimeout > 5000) return;
  }
  timing = ((float) millis() - (float) time1) / 1000.0; //computes time in seconds
  Speed = 0.115 / timing;  //speed in m/s given a separation distance of 11.5 cm
  delay(100);
  Serial.print(Speed);
  Serial.print("\n");  
}

I think the code is more than well commented and needs no further explanation.