Saturday, May 16, 2015

Arduino Ethernet and Weathershield

A combination of the weathershield from sparkfun and the Ethernet-Arduino:

Ethernet-Arduino and the Weathershield
What the webpage looks like:

type the IP-adress directly into the url-bar of your browser

The code:
#include 
#include 
#include  //I2C needed for sensors
#include "MPL3115A2.h" //Pressure sensor
#include "HTU21D.h" //Humidity sensor

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 0, 12);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
String HTTP_req;          // stores the HTTP request

MPL3115A2 myPressure; //Create an instance of the pressure sensor
HTU21D myHumidity; //Create an instance of the humidity sensor

// analog I/O pins
const byte REFERENCE_3V3 = A3;
const byte LIGHT = A1;
const byte BATT = A2;
const byte WDIR = A0;
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

//Global Variables

//These are all the weather values that wunderground expects:
float humidity = 0; // [%]
float tempf = 0; // [temperature F]
//float baromin = 30.03;// [barom in] - It's hard to calculate baromin locally, do this in the agent
float pressure = 0;
//float dewptf; // [dewpoint F] - It's hard to calculate dewpoint locally, do this in the agent

float light_lvl = 455; //[analog value from 0 to 1023]

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  
  pinMode(REFERENCE_3V3, INPUT);
  pinMode(LIGHT, INPUT);

  //Configure the pressure sensor
  myPressure.begin(); // Get sensor online
  myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa
  myPressure.setOversampleRate(7); // Set Oversample to the recommended 128
  myPressure.enableEventFlags(); // Enable all three pressure and temp event flags 

  //Configure the humidity sensor
  myHumidity.begin();


  // turn on interrupts
  interrupts();

  //Serial.println("Weather Shield online!");

}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) 
  {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();
        HTTP_req += c;  // save the HTTP request 1 char at a time
        Serial.write(c);
        // 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) {
          
          calcWeather();
                              
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("");
          client.println("");
          
          client.println("");
          client.println("Weathershield ");          
          client.println("");
          
          client.println("");
          
          client.println("

Wheatershield

"); client.println("Humidity: "); client.println(humidity); client.println("% "); client.println("Temperature: "); client.println(tempf); client.println("°C "); client.println("Pressure: "); client.println(pressure); client.println(" bar "); client.println("Light level: "); client.println(light_lvl); client.println(" lux "); client.println(""); client.println(""); HTTP_req = ""; // finished with request, empty string 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(); Serial.println("client disconnected"); } } //Calculates each of the variables that wunderground is expecting void calcWeather() { //Calc humidity humidity = myHumidity.readHumidity(); //float temp_h = myHumidity.readTemperature(); //Serial.print(" TempH:"); //Serial.print(temp_h, 2); //Calc tempf from pressure sensor tempf = myPressure.readTempF(); //conversion into Celsius tempf = (tempf-32)/1.8; //Serial.print(" TempP:"); //Serial.print(tempf, 2); //Calc pressure pressure = myPressure.readPressure(); //convert to bar pressure = pressure/100000; //Calc light level light_lvl = get_light_level(); } //Returns the voltage of the light sensor based on the 3.3V rail //This allows us to ignore what VCC might be (an Arduino plugged into USB has VCC of 4.5 to 5.2V) float get_light_level() { float operatingVoltage = analogRead(REFERENCE_3V3); float lightSensor = analogRead(LIGHT); operatingVoltage = 3.3 / operatingVoltage; //The reference voltage is 3.3V lightSensor = operatingVoltage * lightSensor; return(lightSensor); }

Wednesday, February 18, 2015

Minimalistic Arduino

In order to build a minimalistic Arduino, you need:
  • one 10kOhm resistor
  • two 22pF capacitors
  • one 100nF capacitor
  • one 16.000Mhz quartz oscillator
  • the ATMEGA 328P-chip (best with preinstalled bootloader)
  • a 5V Voltage-supply and some wiring
  • something for programming the chip (existing Arduino-Board or a USB-FTDI-Serial converter)
optional:
  • one LED and a 150 Ohm resistor (two of both if you want one for the voltage supply as well)
  • switch (Reset switch)
  • USB-FTDI-Serialchip / Arduinoboard
the basic schematic:
minimalistic Ardunio schematic (with optional reset-switch)
If you like the default LED on PIN 13 on the original Arduinoboard, connect first the LED to Pin 19  (right after AVCC), then the 150 Ohm resistor to the LED and the other end to ground.

If you want to supply your project with for example 9V from a battery you can build a simple voltageregulator like this (not suited for AC-Input!):

simple DC-Voltageregulator
all you need is a LM7805 and two 10uF capacitors. If you want, you can connect a LED with resistor to the 5V output (in order to see if the Atmega is under power).

If you are using a USB-FTDI-Serialchip (UFSC) connect the DTR/RST-PIN to the RESET-Pin of the Atmega via a 100nF capacitor. RX of the UFSC goes to the TX of the Atmega and the TX of the UFSC goes to the RX-Pin of the Atmega.

Sunday, February 8, 2015

Arduino & EasyDriver & Steppermotor

If you'd like to run a steppermotor with your Arduino, you're going to need a EasyDriver. This chip allows you to connect a variety of different steppermotors and supply them with their needed voltage (in most cases 12 V). Most common steppermotors will have four wires comming out of them which connect as follows:

Wiring of the EasyDriver, the Arduino and the steppermotor (LED is optional)

If you have a motor with six wires comming out of it, try connecting the two outer and the two inner wires to the chip.

The following Arduinocode has been modified so that you can connect up to three EasyDriver-chips. If you like you can connect three LEDs to Pins 11, 12 and 13 in order to see which motor is supposed to be running (don't forget to use appropriate resistors).

//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Using the easy stepper with your arduino
//use rotate and/or rotateDeg to controll stepper motor
//speed is any number from .01 -> 1 with 1 being fastest - 
//Slower Speed == Stronger movement
//code-change (2015): run up to three motors:
//motor 1: connected to PIN 2 and 3
//motor 2: connected to PIN 4 and 5
//motor 3: connected to PIN 6 and 7
//connect LEDs to PIN 11,12 and 13 to see which motor is supposed to be running
/////////////////////////////////////////////////////////////////

#define DIR_PIN 2
#define STEP_PIN 3
#define DIR_PINt 4
#define STEP_PINt 5
#define DIR_PINth 6
#define STEP_PINth 7

void setup() 
{
  pinMode(DIR_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PINt, OUTPUT);
  pinMode(STEP_PINt, OUTPUT);
  pinMode(DIR_PINth, OUTPUT);
  pinMode(STEP_PINth, OUTPUT);
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
} 

void loop()
{ 

  int dir = (steps > 0)? HIGH:LOW;
  steps = abs(steps);

  switch(motor){
    case 1:
    digitalWrite(DIR_PIN,dir); 
    break;
    case 2:
    digitalWrite(DIR_PINt,dir); 
    break;
    case 3:
    digitalWrite(DIR_PINth,dir); 
    break;
    default:
    break;
  }
  
  float usDelay = (1/speed) * 70;

  for(int i=0; i < steps; i++)
  {
    switch(motor){
      case 1:
      digitalWrite(STEP_PIN, HIGH);
      digitalWrite(13,HIGH);
      delayMicroseconds(usDelay);
      digitalWrite(STEP_PIN, LOW);
      digitalWrite(13,LOW);
      break;
      case 2:
      digitalWrite(STEP_PINt, HIGH);
      digitalWrite(12,HIGH);
      delayMicroseconds(usDelay); 
      digitalWrite(12,LOW);
      digitalWrite(STEP_PINt, LOW);      
      break;
      case 3:
      digitalWrite(STEP_PINth, HIGH);
      digitalWrite(11,HIGH);
      delayMicroseconds(usDelay); 
      digitalWrite(11,LOW);
      digitalWrite(STEP_PINth, LOW);
      break;
      default:
      break;
    }

    delayMicroseconds(usDelay);
  }
} 

void rotateDeg(float deg, float speed, int motor)
{
  //rotate a specific number of degrees (negitive for reverse movement)
  //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger
  //motor specifies which motor to turn (number between 1 and 3)
  int dir = (deg > 0)? HIGH:LOW;
  switch(motor){
    case 1:
    digitalWrite(DIR_PIN,dir); 
    break;
    case 2:
    digitalWrite(DIR_PINt,dir);
    break;
    case 3:
    digitalWrite(DIR_PINth,dir);
    break;
    default:
    break;
  }
 
  int steps = abs(deg)*(1/0.225);
  float usDelay = (1/speed) * 70;

  for(int i=0; i < steps; i++){
    switch(motor){
      case 1:
      digitalWrite(13,HIGH);
      digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(usDelay); 
      digitalWrite(13,LOW);
      digitalWrite(STEP_PIN, LOW);
      break;
      case 2:
      digitalWrite(STEP_PINt, HIGH);
      digitalWrite(12,HIGH);
      delayMicroseconds(usDelay); 
      digitalWrite(12,LOW);
      digitalWrite(STEP_PINt, LOW);
      break;
      case 3:
      digitalWrite(STEP_PINth, HIGH);
      digitalWrite(11,HIGH);
      delayMicroseconds(usDelay); 
      digitalWrite(11,LOW);
      digitalWrite(STEP_PINth, LOW);
      break;
      default:
      break;
    }
    delayMicroseconds(usDelay);
  }
}

The EasyDriver has a few more connectors you can use:
 
EasyDriver-chip

Most important are ENABLE and SLP (Sleep). You can connect each of them to a seperate Arduino PIN and use the digitalWrite(PIN, HIGH) command to activate them. The difference between these two:
  • ENABLE set to HIGH will stop the powersupply to the steppermotor (you will be able to turn the motor shaft by hand), the IC is still under power.
  • SLP set to LOW will stop the powersupply of the motor and will put the IC into a hibernate-mode. Waking the IC up again can take some time (a few ms)

Monday, September 22, 2014

Arduino, QC1602A and HC-SR04

There are two ways to connect a LCD-Display and an Arduino: Via I2C or by connecting them as follows:

Wiring of the Arduino, HC-SR04 and the LCD-Display


The Arduino-Code:
#include <LiquidCrystal.h>
/*
LCD-Connection:
VSS to GND
VDD to +5V
VO to potentiometer to GND
RS to 12
RW to 11
E to 10
D4 to 5
D5 to 4
D6 to 3
D7 to 2
A to 13 
K to GND

HC-SR04-Connection:
VCC to +5V
Trig to 8
Echo to 7
GND to GND

LED-Connection:
(GND-Resistor-LED)
green LED to 6
red LED to 9
*/


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int backLight = 13; //pin 13 for Background-light


#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define erPin 9 //Pin for reed LED
#define goPin 6 //Pin for green LED

int maximumRange = 2000; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance

void setup()
{
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(erPin, OUTPUT);
  pinMode(goPin,OUTPUT);
  
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
    
}


void loop() {
/* The following trigPin/echoPin cycle is used to determine the
 distance of the nearest object by bouncing soundwaves off of it. */ 
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 
 //Calculate the distance (in mm) based on the speed of sound.
 distance = duration/5.82;
 
 if (distance >= maximumRange || distance <= minimumRange){
 /* Send a negative number to computer and Turn LED ON 
 to indicate "out of range" */
 // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.clear();
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print("-1");
  digitalWrite(erPin, HIGH);
  digitalWrite(goPin, LOW);
  

 }
 else {
 /* Send the distance to the computer using Serial protocol, and
 turn LED OFF to indicate successful reading. */
 // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.clear();
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(distance);
  digitalWrite(erPin,LOW);
  digitalWrite(goPin, HIGH);
 

 }
 
 //Delay 50ms before next reading.
 delay(100);
}