Posts with «tutorial» label

Cant find a tutorial !

Hi everyone,

Recently I came across some very good hexapods designed with 6,8 and even 12 servos.I have a duemilanove and would like to build one.

But unfortunately I have not ventured into this domain and my search for a step by step tutorial on google(on multilegged critters like hexapod) and instructables proved futile.Any Links that can help me get started or rather a complete tutorial link would be awesome.Thanks!

Data-logging made simple with Arduino

One of the best capabilities provided by Arduino regards its very high modularity, which helps users to quickly translate ideas into physical artifact, as practically demonstrated by Mauro, which shows on his blog how to build a simple data-logger by properly combining different shields. By using few additional components (mainly resistors and buttons) a fully-functional data logger can be easily implemented.

More information can be found here.

[Via: Mauro Alfieri's blog]

Arduino Blog 23 Jan 20:00

MakerLab reviews the Arduino Starter Kit

When we released the Arduino Kit, we knew that we are equiping the closet-wannabe-makers to start planning for world domination. Now it has the stamp of approval from MakerLab too!

Make Noise With The New Arduino Kit is a project by Alessandro Contini (@CNTLSN) and Alberto Massa (@nkint)

The above video explores the basic components of the kit and things that a new-maker would want to start with, including a light controlled theramin, and by theramin, I really mean exploring every possibe way to make impressive noises from one simple experiment.

Sounds fun? Do write to us, what you made out of your starter kit. We may feature you next

Via:[MakerLab]

Arduino Blog 22 Jan 11:45

Bluetooth Tutorial 1


Introduction:
The bluetooth shield used in this project is a great way to detach the Arduino from your computer. What is even better, is that the shield allows you to control your arduino from your mobile phone or other bluetooth enabled device through simple Serial commands. In this tutorial we will connect a Grove Chainable RGB LED to the bluetooth shield directly, and send simple commands using the Bluetooth SPP app on a Samsung Galaxy S2 to change the colour of the LED (Red , Green and Blue)



Parts Required:
Freetronics Eleven or any compatible Arduino.
Bluetooth shield
Grove Chainable RGB LED
Grove Wire connectors




The Video:





The Arduino Sketch:








Arduino Code:
You can download the Arduino IDE from this site.


 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* This project combines the code from a few different sources.
This project was put together by ScottC on the 15/01/2013
http://arduinobasics.blogspot.com/

Bluetooth slave code by Steve Chang - downloaded from :
http://www.seeedstudio.com/wiki/index.php?title=Bluetooth_Shield

Grove Chainable RGB code can be found here :
http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED#Introduction

*/

#include <SoftwareSerial.h> //Software Serial Port

#define uint8 unsigned char
#define uint16 unsigned int
#define uint32 unsigned long int

#define RxD 6 // This is the pin that the Bluetooth (BT_TX) will transmit to the Arduino (RxD)
#define TxD 7 // This is the pin that the Bluetooth (BT_RX) will receive from the Arduino (TxD)

#define DEBUG_ENABLED 1


int Clkpin = 9; //RGB LED Clock Pin (Digital 9)
int Datapin = 8; //RGB LED Data Pin (Digital 8)

SoftwareSerial blueToothSerial(RxD,TxD);

/*----------------------SETUP----------------------------*/
void setup() {
Serial.begin(9600); // Allow Serial communication via USB cable to computer (if required)
pinMode(RxD, INPUT); // Setup the Arduino to receive INPUT from the bluetooth shield on Digital Pin 6
pinMode(TxD, OUTPUT); // Setup the Arduino to send data (OUTPUT) to the bluetooth shield on Digital Pin 7
pinMode(13,OUTPUT); // Use onboard LED if required.
setupBlueToothConnection(); //Used to initialise the Bluetooth shield

pinMode(Datapin, OUTPUT); // Setup the RGB LED Data Pin
pinMode(Clkpin, OUTPUT); // Setup the RGB LED Clock pin

}

/*----------------------LOOP----------------------------*/
void loop() {
digitalWrite(13,LOW); //Turn off the onboard Arduino LED
char recvChar;
while(1){
if(blueToothSerial.available()){//check if there's any data sent from the remote bluetooth shield
recvChar = blueToothSerial.read();
Serial.print(recvChar); // Print the character received to the Serial Monitor (if required)

//If the character received = 'r' , then change the RGB led to display a RED colour
if(recvChar=='r'){
Send32Zero(); // begin
DataDealWithAndSend(255, 0, 0); // first node data
Send32Zero(); // send to update data
}

//If the character received = 'g' , then change the RGB led to display a GREEN colour
if(recvChar=='g'){
Send32Zero(); // begin
DataDealWithAndSend(0, 255, 0); // first node data
Send32Zero(); // send to update data
}

//If the character received = 'b' , then change the RGB led to display a BLUE colour
if(recvChar=='b'){
Send32Zero(); // begin
DataDealWithAndSend(0, 0, 255); // first node data
Send32Zero(); // send to update data
}
}

//You can use the following code to deal with any information coming from the Computer (serial monitor)
if(Serial.available()){
recvChar = Serial.read();

//This will send value obtained (recvChar) to the phone. The value will be displayed on the phone.
blueToothSerial.print(recvChar);
}
}
}


//The following code is necessary to setup the bluetooth shield ------copy and paste----------------
void setupBlueToothConnection()
{
blueToothSerial.begin(38400); //Set BluetoothBee BaudRate to default baud rate 38400
blueToothSerial.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
blueToothSerial.print("\r\n+STNA=SeeedBTSlave\r\n"); //set the bluetooth name as "SeeedBTSlave"
blueToothSerial.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
blueToothSerial.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000); // This delay is required.
blueToothSerial.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
Serial.println("The slave bluetooth is inquirable!");
delay(2000); // This delay is required.
blueToothSerial.flush();
}


//The following code snippets are used update the colour of the RGB LED-----copy and paste------------
void ClkProduce(void){
digitalWrite(Clkpin, LOW);
delayMicroseconds(20);
digitalWrite(Clkpin, HIGH);
delayMicroseconds(20);
}

void Send32Zero(void){
unsigned char i;
for (i=0; i<32; i++){
digitalWrite(Datapin, LOW);
ClkProduce();
}
}

uint8 TakeAntiCode(uint8 dat){
uint8 tmp = 0;
if ((dat & 0x80) == 0){
tmp |= 0x02;
}

if ((dat & 0x40) == 0){
tmp |= 0x01;
}

return tmp;
}

// gray data
void DatSend(uint32 dx){
uint8 i;
for (i=0; i<32; i++){
if ((dx & 0x80000000) != 0){
digitalWrite(Datapin, HIGH);
} else {
digitalWrite(Datapin, LOW);
}

dx <<= 1;
ClkProduce();
}
}

// data processing
void DataDealWithAndSend(uint8 r, uint8 g, uint8 b){
uint32 dx = 0;

dx |= (uint32)0x03 << 30; // highest two bits 1,flag bits
dx |= (uint32)TakeAntiCode(b) << 28;
dx |= (uint32)TakeAntiCode(g) << 26;
dx |= (uint32)TakeAntiCode(r) << 24;

dx |= (uint32)b << 16;
dx |= (uint32)g << 8;
dx |= r;

DatSend(dx);
}

The code above was formatted using hilite.me

Notes:
You don't need to download a library to get this project running. But if you plan to use bluetooth shields to get 2 Arduinos to communicate to each other, then I would advise that you download the library files (which are just examples) from the Seeedstudio site : here.

Visit this site to setup your phone or laptop for bluetooth communication to the shield - here

The app used on my Samsung Galaxy S2 phone was "Bluetooth SPP"

You will initially need to enter a pin of '0000' to establish a connection to the Bluetooth shield - which will appear as "SeeedBTSlave" or whatever text you place on line 90 of the Arduino code above.





Warning !

Not all phones are compatible with the bluetooth shield.
If you have used this shield before - please let me know what phone you used - so that we can build a list and inform others whether their phone is likely to work with this project or not. Obviously - those phones that do not have bluetooth within - will not work :).
And I have not tried any other apps either

I got it to work very easily with my Samsung Galaxy S2 using the free Bluetooth SPP app from the google play store.

This was fun, but I want to make my own app !
Have a look at my latest 4-part tutorial which takes you step-by-step through the process of building your own app using the Processing/Android IDE.
You can build your own GUI interface on your Android Phone and get it to communicate via Bluetooth to your Arduino/Bluetooth Shield. Click on the links below for more information:




 
 



If you like this page, please do me a favour and show your appreciation :

 
Visit my ArduinoBasics Google + page.
Follow me on Twitter by looking for ScottC @ArduinoBasics.
Have a look at my videos on my YouTube channel.


 
 

 
 
 



However, if you do not have a google profile...
Feel free to share this page with your friends in any way you see fit.

Sonar Project Tutorial


Introduction:
This project utilises the HC-SR04 ultrasonic sensor to scan for nearby objects. You can program the Arduino to sound an alarm when the sensor detects an object within a specific vicinity. Connecting it to a computer allows data to be plotted to make a simple sonar scanner. The scanning ability is made possible through the use of a hobby servo motor SG-5010, and an Adafruit motor shield v1.0.
This project could easily be extended to provide object avoidance for any robotics project. This tutorial was designed so that you could see how the components interact, and also to see how you can use and expand the functionality of the motor shield.



Parts Required:
Freetronics Eleven or any compatible Arduino.
Adafruit motor shield v1.0
HC-SR04 Ultrasonic Sensor
MG-995  or SG-5010 Standard servo
Mini Breadboard 4.5cm x 3.5cm
Female header pins to allow easy access to the analog pins on the Motor Shield
Piezo buzzer - to sound alarm
9V Battery and Battery Clip
Wiresto connect it all together

Gauge parts:

Paper (to print the face of the gauge), and some glue to stick it to the wood.
MDF Standard panel (3mm width) - for the top and base of the gauge, and the pointer.
Galvanized bracket (25x25x40mm)
Timber screws: Hinge-long threads csk head Phillips drive (4G x 12mm)
Velcro dots - to allow temporary application of the mini-breadboard to the gauge.

The gauge was used as a customisable housing for the Arduino and related parts, and to provide some visual feedback of the servo position.



The Video:




The Arduino Sketch:


 Part of the sketch above was created using Fritzing.

The Servo motor can be connected to either of the Servo motor pins (Digital 9 or 10). In this case, the Servo is attached to digital pin 10.Make sure you read the servo motor data sheet and identify the VCC (5V), GND, and Signal connectors. Not all servos have the same colour wires. My servo motor has a white signal wire, a red VCC wire and a black GND wire.

Also when connecting your wires to the HC-SR04, pay attention to the front of the sensor. It will identify the pins for you. Make sure you have the sensor facing the correct way. In this sketch, the sensor is actually facing towards you.

In this sketch - we connect the
    Echo pin to Analog pin 0 (A0).
    Trigger pin to Analog pin 1 (A1)
    VCC to a 5V line/pin 
    and GND to a GND line/pin

Pay attention to your motor shield, I have seen some pictures on the internet where the 5V and GND are reversed.





Arduino Code:
You can download the Arduino IDE from this site.

The motor shield requires the Adafruit motor shield driver library to be installed into the Arduino IDE.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* ArduinoBasics: Sonar Project - Created by Scott C on 10 Jan 2013
http://arduinobasics.blogspot.com/2013/01/arduino-basics-sonar-project-tutorial.html

This project uses the Adafruit Motor shield library (copyright Adafruit Industries LLC, 2009
this code is public domain, enjoy!)

The HC-SR04 sensor uses some code from the following sources:
From Virtualmix: http://goo.gl/kJ8Gl
Modified by Winkle ink here: http://winkleink.blogspot.com.au/2012/05/arduino-hc-sr04-ultrasonic-distance.html
And modified further by ScottC here: http://arduinobasics.blogspot.com/
on 10 Nov 2012.
*/

#include <AFMotor.h>
#include <Servo.h>

// DC hobby servo
Servo servo1;

/* The servo minimum and maximum angle rotation */
static const int minAngle = 0;
static const int maxAngle = 176;
int servoAngle;
int servoPos;
int servoPin = 10;


/* Define pins for HC-SR04 ultrasonic sensor */
#define echoPin A0 // Echo Pin = Analog Pin 0
#define trigPin A1 // Trigger Pin = Analog Pin 1
#define LEDPin 13 // Onboard LED
long duration; // Duration used to calculate distance
long HR_dist=0; // Calculated Distance
int HR_angle=0; // The angle in which the servo/sensor is pointing
int HR_dir=1; // Used to change the direction of the servo/sensor
int minimumRange=5; //Minimum Sonar range
int maximumRange=200; //Maximum Sonar Range

/*--------------------SETUP()------------------------*/
void setup() {
//Begin Serial communication using a 9600 baud rate
Serial.begin (9600);

// Tell the arduino that the servo is attached to Digital pin 10.
servo1.attach(servoPin);

//Setup the trigger and Echo pins of the HC-SR04 sensor
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}

/*----------------------LOOP()--------------------------*/
void loop() {

/* check if data has been sent from the computer: */
if (Serial.available()) {

/* This expects an integer from the Serial buffer */
HR_angle = Serial.parseInt();

/* If the angle provided is 0 or greater, then move servo to that
position/angle and then get a reading from the ultrasonic sensor */
if(HR_angle>-1){
/*Make sure that the angle provided does not go beyond the capabilities
of the Servo. This can also be used to calibrate the servo angle */
servoPos = constrain(map(HR_angle, 0,180,minAngle,maxAngle),minAngle,maxAngle);
servo1.write(servoPos);

/* Call the getDistance function to take a reading from the Ultrasonic sensor */
getDistance();
}
}
}

/*--------------------getDistance() FUNCTION ---------------*/
void getDistance(){

/* 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 cm) based on the speed of sound.
HR_dist = duration/58.2;

/*Send the reading from the ultrasonic sensor to the computer */
if (HR_dist >= maximumRange || HR_dist <= minimumRange){
/* Send a 0 to computer and Turn LED ON to indicate "out of range" */
Serial.println("0");
digitalWrite(LEDPin, HIGH);
} else {
/* Send the distance to the computer using Serial protocol, and
turn LED OFF to indicate successful reading. */
Serial.println(HR_dist);
digitalWrite(LEDPin, LOW);
}
}

The code above was formatted using hilite.me

Notes:
Servo Angles: You will notice on line 22, the maximum servo angle used was 176. This value was obtained through trial and error (see below).

Calibrating the servo angles
You may need to calibrate your servo in order to move through an angle of 0 to 180 degrees without straining the motor. Go to line 21-22 and change the minAngle to 0 and the maxAngle to 180. Once you load the sketch to the Arduino/Freetronics ELEVEN, you can then open the Serial Monitor and type a value like 10 <enter>, and then keep reducing it until you get to 0. If you hear the servo motor straining, then move it back up to a safe value and change the minimum servo angle to that value. Do the same for the maximum value.

In this example, the servo's minAngle value was 0, and maxAngle value was 176 after calibration, however, as you can see from the video, the physical range of the servo turned out to be 0 to 180 degrees.




The Processing Sketch

You can download the Processing IDE from this site.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* Created by ScottC on 10 Jan 2013 
http://arduinobasics.blogspot.com/2013/01/arduino-basics-sonar-project-tutorial.html
*/

import processing.serial.*;

int distance;
int angle=0;
int direction=1;

int[] alphaVal = new int[100]; // used to fade the lines
int[] distance2 = new int[100]; // used to store the line lengths
int lineSize = 4; // line length multiplier (makes it longer)

String comPortString;
Serial comPort;

/*---------------------SETUP---------------------------*/
void setup( ) {
size(displayWidth,displayHeight); //allows fullscreen view
smooth();
background(0); // set the background to black

/*Open the serial port for communication with the Arduino
Make sure the COM port is correct - I am using COM port 8 */
comPort = new Serial(this, "COM8", 9600);
comPort.bufferUntil('\n'); // Trigger a SerialEvent on new line

/*Initialise the line alphaValues to 0 (ie not visible) */
for(int i=0; i<91; i++){
alphaVal[i] = 0;
}
}

/*---------------------DRAW-----------------*/
void draw( ) {
background(0); //clear the screen

/*Draw each line and dot */
for(int i=0; i<91; i++){

/*Gradually fade each line */
alphaVal[i]=alphaVal[i]-4;

/*Once it gets to 0, keep it there */
if(alphaVal[i]<0){
alphaVal[i]=0;
}

/*The colour of the line will change depending on the distance */
stroke(255,distance2[i],0,alphaVal[i]);

/* Use a line thickness of 2 (strokeweight) to draw the line that fans
out from the bottom center of the screen. */
strokeWeight(2);
line(width/2, height, (width/2)-cos(radians(i*2))*(distance2[i]*lineSize), height-sin(radians(i*2))*(distance2[i]*lineSize));

/* Draw the white dot at the end of the line which does not fade */
stroke(255);
strokeWeight(1);
ellipse((width/2)-cos(radians(i*2))*(distance2[i]*lineSize), height-sin(radians(i*2))*(distance2[i]*lineSize),5,5);
}
}

/* A mouse press starts the scan. There is no stop button */
void mousePressed(){
sendAngle();
}

/*When the computer receives a value from the Arduino, it will update the line positions */
void serialEvent(Serial cPort){
comPortString = cPort.readStringUntil('\n');
if(comPortString != null) {
comPortString=trim(comPortString);

/* Use the distance received by the Arduino to modify the lines */
distance = int(map(Integer.parseInt(comPortString),1,200,1,height));
drawSonar(angle,distance);

/* Send the next angle to be measured by the Arduino */
sendAngle();
}
}

/*---------------------------sendAngle() FUNCTION----------------*/
void sendAngle(){
//Send the angle to the Arduino. The fullstop at the end is necessary.
comPort.write(angle+".");

/*Increment the angle for the next time round. Making sure that the angle sent
does not exceed the servo limits. The "direction" variable allows the servo
to have a sweeping action.*/
angle=angle+(2*direction);
if(angle>178||angle<1){
direction=direction*-1;
}
}

/*-----------------sketchFullScreen(): Allows for FullScreen view------*/
boolean sketchFullScreen() {
return true;
}

/*----------------- drawSonar(): update the line/dot positions---------*/
void drawSonar(int sonAngle, int newDist){
alphaVal[sonAngle/2] = 180;
distance2[sonAngle/2] = newDist;
}



The Processing Output


 

Analog IR Temperature gauge


Introduction:
The IRTEMP module from Freetronics is an infrared remote temperature sensor that can be incorporated into your Arduino / microcontroller projects. It can scan a temperature between -33 to +220 C, and can be operated using a 3.3 to 5V power supply. It can be powered directly from the Arduino 5V pin.  This module can also provide an ambient temperature reading if required.
The Servo used in this project is a SG-5010 standard servo which will be utilised to display the temperature reading from the IRTEMP module.



Parts Required:
Freetronics Eleven or any compatible Arduino.
Freetronics IRTEMP module
MG-995  or SG-5010 Standard servo
Mini Breadboard 4.5cm x 3.5cm
Protoshieldand female header pins (not essential - but makes it more tidy)
9V Battery and Battery Clip
Wiresto connect it all together

Gauge parts:
Paper (to print the face of the gauge), and some glue to stick it to the wood.
MDF Standard panel (3mm width) - for the top and base of the gauge.
Galvanized bracket (25x25x40mm)
Timber screws: Hinge-long threads csk head Phillips drive (4G x 12mm)





The Video:



The Arduino Sketch:



     The above sketch was created using Fritzing.





Arduino Code:
You can download the Arduino IDE from this site.

The IRTemp gauge requires a driver library to be installed into the Arduino IDE.
The latest IRTemp driver library can be found here.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* -------------------------------------------------------
Analog IR Temperature Gauge: written by ScottC on 1st Dec 2012.
http://arduinobasics.blogspot.com/2012/12/arduino-basics-analog-ir-temperature.html


* Some of the code was adapted from a sketch by Andy Gelme (@geekscape)
* For more information on using the IRTEMP
see www.freetronics.com/irtemp

* IRTemp library uses an Arduino interrupt:
* If PIN_CLOCK = 2, then Arduino interrupt 0 is used
* If PIN_CLOCK = 3, then Arduino interrupt 1 is used
---------------------------------------------------------*/

#include "IRTemp.h"
#include <Servo.h>

Servo servo1;
static const byte PIN_DATA = 2;
static const byte PIN_CLOCK = 3; // Must be either pin 2 or pin 3
static const byte PIN_ACQUIRE = 4;

static const bool SCALE=false; // Celcius: false, Farenheit: true

/* Used to capture the temperature from the IRTEMP sensor */
float irTemperature;
int temp;

/* The minimum and maximum temperatures on the gauge. */
static const int minTemp = -45;
static const int maxTemp = 135;


/* The servo minimum and maximum angle rotation */
static const int minAngle = 0;
static const int maxAngle = 175;
int servoPos;

IRTemp irTemp(PIN_ACQUIRE, PIN_CLOCK, PIN_DATA);



/*----------------------SETUP----------------------*/

void setup(void) {

servo1.attach(9); // turn on servo
}


/*-----------------------LOOP-----------------------*/

void loop(void) {
irTemperature = irTemp.getIRTemperature(SCALE);
printTemperature("IR", irTemperature);

/* If you want the ambient temperature instead - then use the code below. */
//float ambientTemperature = irTemp.getAmbientTemperature(SCALE);
//printTemperature("Ambient", ambientTemperature);

}

/*-----------printTemperature function---------------*/

void printTemperature(char *type, float temperature) {

temp=(int) temperature;
servoPos = constrain(map(temp, minTemp,maxTemp,minAngle,maxAngle),minAngle,maxAngle);

if (isnan(temperature)) {
//is not a number, do nothing
}
else {

/* To test the minimum angle insert the code below */
//servoPos = minAngle;

/*To test the maximum angle, insert the code below */
//servoPos = maxAngle;

/* Rotate servo to the designated position */
servo1.write(servoPos);
}
}

The code above was formatted using hilite.me

Notes:
Ambient temperature: If you want to get the ambient temperature from the IRTEMP module, then have a look at lines 58-59.
Servo Angles: You will notice on line 36, the maximum servo angle used was 175. This value was obtained through trial and error (see below).

Calibrating the servo angles
You may need to calibrate your servo in order to move through an angle of 0 to 180 degrees without straining the motor.Change the minAngle on line 35to a safe value (for example: 10), and the maxAngle on line 36 to a value like 170. Remove the comment tag (//) on line 76, and then run the sketch. Lower the minAngle until it reaches the minimum value on the gauge, making sure that the servo doesn't sound like it is straining to keep it in position.

Add the comment tag (//) back in, and then take out the comment tag for line 79. And follow a similar process, until you reach the maximum value on the gauge. Once again, make sure that the servo is not making a straining noise to hold it at that value. Make sure to add the comment tag back in, when you have finished the calibration.

In this example, the servo's minAngle value was 0, and maxAngle value was 175 after calibration, however, as you can see from the video, the physical range of the servo turned out to be 0 to 180 degrees.




The Temperature Gauge Picture

The following gauge was created in Microsoft Excel using an X-Y chart.  Data labels were manually repositioned in order to get the desired numerical effect.




Wi-Fi Body Scale with Arduino

In this post we present the design of a scale that connects to the Internet and automatically sends weight info on a Google Document.

The project is composed of

 

Hardware

Taking a look at the diagram, we can distinguish three sections:

one for handling digital inputs (two buttons and scale’s switch),
the LCD manager
the analog signal acquisition from load cells


You may notice that P1 and P2 buttons are respectively managed by Arduino’s A3 and A4 inputs (configured as digital), while the INT switch reads the A5 signal (digital as well).

The LCD display used in our project belongs to the family of those based on HD44780 chipset, equipped with seven-pin control (RW, D4, D5, D6, D7, RS and Enable). As you can see from the diagram, RW is permanently connected to ground so it’s only operating in writing mode.

D4, D5, D6 and D7 pins are respectively managed by 3, 5, 6 and 7 digital pins of the Arduino Uno; RS is managed by pin 8 and the Enable pin from pin A0 (this configuration will also be specified in the software).

Besides the power supply (a VCC connected to 5V) and the ground (GND), the display requires a level of voltage between 0 and 5 volts to adjust the contrast in the input pin VO (adjustment made through R6 potentiometer).

Finally the display has 2 pin (A and K respectively anode and cathode) for switching on the backlight: feeding the pin with a voltage of 5V, the backlight is turned on, otherwise it is off.

The switching on and off is handled via a push-button switch that connects or disconnects the ground from the cathode.

Finally let’s analyze the part that manages the analog signal from the load cells: this is done by INA125 integrated component, a high precision amplifier developed specifically for measuring tools like scales.


The IC is fitted with two pins (6 and 7) representing the input of the differential amplification stage. These pins are connected to the two ends of the Wheatstone bridge (which in our project correspond to two of the load cell pins).

As you can figure out, the differential signal coming from the bridge has an absolute value of just a few millivolts: our project requires an amplification of about 500 times, obtained with a 120 ohm resistor.

The amplified output is provided at pins 10 and 11 of INA125; these pins are connected to A1 analog of the Arduino board, which therefore will be used for reading the value ADC.

R1: 39 ohm
R2: 1 kohm
R3: 4,7 kohm
R4: 4,7 kohm
R5: 330 ohm
R6: Trimmer 10 kohm
R7: 4,7 kohm

C1: 100 nF 63 VL
C2: 100 µF 25 VL

U1: INA125

P1: Microswitch
P2: Microswitch

LCD: Display LCD 8×2

 

Hacking  the Velleman scale

Our system is designed to be matched to the high-capacity scale produced by Velleman. But you can using any scale usign 4 load cells. The original Velleman electronics and display must be phased out and replaced with our project.

The scale structure is made up of 4 load cells (arranged on the 4 corners), which are configured between them so as to create a single Wheatstone bridge.

To make the connection to our board you must disassemble the lower section of the scale in order to access the electronics.

Referring to Fig A, which shows the structure of the scale viewed from below, with a quick visual analysis is easy to figure out that some blue and red wires are connected to each other while the yellow wires are connected to the switches positioned on the front of the two cells that identify the presence of a person.


To hack the scale follow these steps:


  • unsolder or cut all the red and blue wires, push in short those that were already shorted previously,

  • unsolder or cut the yellow wires coming from the cells numbered 1 and 3, put them in parallel (possibly by welding), extend them and take them to the two terminals on the new INT printed board (Fig.B)

  • unsolder or cut the white wire that is referred to as G3 (Wheatstone bridge mass) on the original printed circuit, extend take it to terminal 1 on the new printed circuit;

  • unsolder or cut the white wire that is referred to as G2 (Wheatstone bridge positive) on the original printed circuit, extend take it to terminal 3 on the new printed circuit;

  • unsolder or cut the white wire that is referred to as G1 and G4 on the original printed circuit, extend take it to terminal 4 and 2 on the new printed circuit (differential signal on the Wheatstone bridge)

 


The Sketch

As for the LCD, Arduino provides a convenient library (<LiquidCrystal.h>) already supporting different kinds of LCD (both 8 and 16 chars for 2 lines) based on the parallel interface chipset HD44780.

After the inclusion of the library, you must initialize the connection to the display, through LiquidCrystal LCDDisplay (8, A0, 3, 5, 6, 7), in this command, the parameters passed to the function and indicate Arduino’s hardware pins used to connect RS, Enable, D4, D5, D6 and D7 pins of the display.

Depending on the Arduino setup could be necessary to execute LCDDisplay.begin (width, height) in which the parameters indicate the physical dimensions of the display: LCDDisplay.begin (8, 2) in this case.

The library makes available instructions:

  • LCDDisplay.setCursor (x, y) to position the cursor in a certain position
  • LCDDisplay.print (String) to print strings


Management of Arduino’s EEPROM is done by the <EEPROM.h> library  that, once included, provides the functions:


  • EEPROM.write (add, date) to write a byte in a particular cell and

  • EEPROM.read (add) that the instead reads a byte from one cell (the add parameter specifies the address of the EEPROM cell).


Wi-Fi network and internet connection are managed thanks to the <WiServer.h> library; you just need to define some variables to configure the network (like IP’s and Network masks).


The adapter to connect and publish data on Google Documents shall operate as a Web Client: this configuration is done in the setup instruction WiServer.init (NULL) in which the NULL parameter specifies client mode.


You must create a function that will receive and handle the response from the server, this is done by the googlePublish.setReturnFunc  (Gestione_Risposte_Web) instruction  in our example. This function must be defined later in the code: in our example is void Gestione_Risposte_Web (char * data, int len) and receives as parameters both a pointer to a string containing the response and the length (in bytes) of the response.


Sending information requires to make a POST request to Google’s servers: WiServer library makes available a POSTrequest just to do this.


You must define the IP address of the server to which you want to connect (Google in our case) and define a structure of the POSTrequest (in our case, the variable is called googlePublish) containing the IP address of the server, the TCP / IP port the server name (spreadsheets.google.com), URL of POST execution and finally a function (SearchQuery in our case) that builds POST request body.

 

/******************************************************
 BilanciaWiFi
 Autori: Ingg. Tommaso Giusto e Ing. Alessandro Giusto
 Email:  tommro@libero.it
******************************************************/

// Inclusione Libreria per Display LCD 8x2
#include <LiquidCrystal.h>
// Inclusione Libreria per EEPROM scheda
#include <EEPROM.h>
// Inclusione Libreria per Server Web WiFi
#include <WiServer.h>
// Inclusione Libreria per SD Card
//#include <SD.h>

// Definizione pin INPUT/OUTPUT
const int PinVPeso = A1;         // Ingresso analogico uscita peso
const int PinPulsanteP1 = A3;    // Ingresso pulsante P1 su A3
const int PinPulsanteP2 = A4;    // Ingresso pulsante P2 su A4
const int PinInterruttore = A5;  // Ingresso interruttore su A5

// Definizione/Inizializzazione PIN Display LCD
// LCD RS pin D8
// LCD Enable on pin A0
// LCD D4, D5, D6, D7 on pins D3, D5, D6, D7
// LCD R/W pin a massa
// LCD V0 pin trimmer tra +5V e massa
LiquidCrystal LCDDisplay (8, A0, 3, 5, 6, 7);

/******************************************************
 Definizione struttura EEPROM
******************************************************/

/*****************************************************/
// Byte 0x000        Nome
// ...               Utente
// Byte 0x01F        000 (0x00 Carattere fine stringa)
// ...               
// ...               
// ...               
// Byte 0x120        Nome
// ...               Utente
// Byte 0x13F        009 (0x00 Carattere fine stringa)
/*****************************************************/
#define StartNomiUtentiEEPROMADD          0x0000
#define EndNomiUtentiEEPROMADD            0x013F
#define DimensioneNomeUtenteEEPROMADD     32
#define NumMaxNomiUtenti                  10

/*****************************************************/
// Byte 0x140        Parte Alta Peso Utente 000
// Byte 0x141        Parte Bassa Peso Utente 000
// ...               
// ...               
// ...               
// Byte 0x152        Parte Alta Peso Utente 009
// Byte 0x153        Parte Bassa Peso Utente 009
/*****************************************************/
#define StartPesiUtentiEEPROMADD          0x0140
#define EndPesiUtentiEEPROMADD            0x0153
#define DimensionePesoUtenteEEPROMADD     2

#define PesoMIN                           100
#define PesoMAX                           2000
#define AnalogDifferenzaPesoMAX           15

#define CalibrazioneSensoreMIN            0
#define CalibrazioneSensoreMAX            80

/******************************************************
 Definizione variabili globali
******************************************************/

// Definizione Parametri Rete Wireless
#define WIRELESS_MODE_INFRA	1  // Infrastrutturata (basata su Access Point)
#define WIRELESS_MODE_ADHOC	2  // Ad-hoc (senza Access Point)

// Parametri di rete
unsigned char local_ip[] = {192, 168, 0, 89};      // Indirizzo IP
unsigned char gateway_ip[] = {192, 168, 0, 254};	    // Indirizzo gateway IP
unsigned char subnet_mask[] = {255, 255, 255, 0};   // Subnet Mask
const prog_char ssid[] PROGMEM = {"FlashMob"};	    // SSID access point

// Selezione tipo di cifratura rete Wireless
unsigned char security_type = 0;  // 0 -> nessuna cifratura
                                  // 1 -> cifratura WEP
                                  // 2 -> cifratura WPA
                                  // 3 -> cifratura WPA2

// Password cifratura per WPA/WPA2 (max. 64 cratteri)
const prog_char security_passphrase[] PROGMEM = {"12345678"};

// Password cifratura per WEP 128-bit keys
prog_uchar wep_keys[] PROGMEM = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
				 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

// Selezione tipo di rete Wireless infrastrutturata
unsigned char wireless_mode = WIRELESS_MODE_INFRA;

// Variabili per lunghezza SSID e password di cifratura
unsigned char ssid_len;
unsigned char security_passphrase_len;

// Definizione Parametri Pubblicazione Google
// Indirizzo IP per server www.google.it
uint8 google_ip[] = {209, 85, 229, 101};

// Richiesta POST verso GOOGLE
POSTrequest googlePublish (google_ip, 80, "spreadsheets.google.com", "", searchQuery);

// Stringa per eseguire pubblicazione
char newURL[] = {"/formResponse?formkey=dDFPcWhxNlZxMEpnUnhNdE5fT1lDcWc6MQ&ifq&entry.0.single=++++++++++++++++++++++++++++++++&entry.1.single=999,9&submit=Submit"};

// This function generates the body of our POST request
void searchQuery() {
}

// Indica presenza SD Card
//boolean presenzaSDCard;

// Inizializzazione Scheda
void setup() {
  // Inizializzo dimensioni LCD (8x2)
  LCDDisplay.begin (8, 2);

  // Inizializzo pin usati come INPUT/OUTPUT
  pinMode (PinInterruttore, INPUT);  
  pinMode (PinPulsanteP1, INPUT);
  pinMode (PinPulsanteP2, INPUT);

  // Se all'accensione rilevati tutti e 2 i pulsanti premuti
  if ((PulsantePremuto (PinPulsanteP1) == 1) &&
      (PulsantePremuto (PinPulsanteP2) == 1)) {
    // Segnalo inizializzazione in corso
    LCDDisplay.setCursor (0, 0);
    LCDDisplay.print ("Init EEP");
    LCDDisplay.setCursor (0, 1);
    LCDDisplay.print ("in corso");

    // Inizializzo EEPROM scheda
    InizializzaEEPROM();
    // Attesa
    delay (500);
  }
  // Inizializzo porta seriale
  Serial.begin (9600);  
  Serial.println ("Bilancia WiFi");
  Serial.println ("By Ingg. Tommaso e Alessandro Giusto");
  // Invio stato utenti
  InviaProgrammazioneUtenti();

  // Segnalo Avvio Web
  LCDDisplay.setCursor (0, 0);
  LCDDisplay.print ("  Init  ");
  LCDDisplay.setCursor (0, 1);
  LCDDisplay.print ("  web   ");  

  // Inizializzo WiServer
  WiServer.init (NULL);
  WiServer.enableVerboseMode (false);

  // Inizializzazione richiesta POST (parametro indica funzione a cui verra' passata la risposta)
  googlePublish.setReturnFunc (Gestione_Risposte_Web);    

/*
  // Inizializzo SD Card
  pinMode(10, OUTPUT);  
  presenzaSDCard = SD.begin (4);
  // Se inizializzazione SD fallita  
  if (presenzaSDCard == false)
    Serial.println ("Init SD FAULT!");
  // Se inizializzazione SD riuscita
  else
    Serial.println ("Init SD OK!");
*/
}

// Programma Principale
void loop() {
  // Ciclo infinito di esecuzione
  for (;;) {
    // Gestione Peso
    GestionePeso();

    // Per circa 1 sec
    for (byte tmp = 0; tmp < 250; tmp++) {
      // Gestione programmazione seriale
      GestioneSeriale();
      // Gestione WiServer
      GestioneWiServer();
      // Attesa
      delay (4);
    }    // Chiusura ciclo for per circa 1 sec
  }    // Chiusura ciclo infinito di esecuzione
}

/******************************************************
 Definizione funzioni
******************************************************/

// Funzione Gestione Peso
void GestionePeso() {
  // Indice utente selezionato
  //    0,..,(NumMaxNomiUtenti-1) -> selezionato utente 1,..,NumMaxNomiUtenti
  //    0xFF -> nessun utente selezionato
  static int IndiceUtenteSelezionato = 0xFF;
  // Indica l'indice carattere visualizzato  
  static int IndiceCarattere = 0;
  String NomeUtenteSelezionato;
  int PesoUtenteSelezionato;
  int LunghezzaNomeUtenteSelezionato;
  int ValoreSensorePeso1, ValoreSensorePeso2;
  int ValoreSensorePesoTMP1, ValoreSensorePesoTMP2, ValoreSensorePesoTMP3, ValoreSensorePesoTMP4;
  static int CalibrazioneSensore;
  int CalibrazioneSensoreTMP;
  int PesoCalcolato;
  int tmp;

  // Se non premuto interruttore (utente non salito)
  if (PulsantePremuto (PinInterruttore) == 0) {
    // Leggo valore sensore per calibrazione
    CalibrazioneSensoreTMP = analogRead (PinVPeso);
    // Se valore sensore per calibrazione valido
    if ((CalibrazioneSensoreTMP >= (int) (CalibrazioneSensoreMIN)) &&
      (CalibrazioneSensoreTMP <= (int) (CalibrazioneSensoreMAX)))
      // Aggiorno valore sensore per calibrazione
      CalibrazioneSensore = CalibrazioneSensoreTMP;
  }    // Chiusura if non premuto interruttore (utente non salito)

  // Se premuto tasto 1
  if (PulsantePremuto (PinPulsanteP1) == 1) {
    // Azzero indice carattere visualizzato
    IndiceCarattere = 0;

    // Verifico tutte le posizioni utente
    for (tmp = 0; tmp < NumMaxNomiUtenti; tmp++) {
      // Seleziono utente selezionato
      switch (IndiceUtenteSelezionato) {
        // Se selezionato ultimo utente/nessun utente selezionato
        case (NumMaxNomiUtenti - 1): case 0xFF:
          // Seleziono primo utente
          IndiceUtenteSelezionato = 0;
          break;    // Chiusura case selezionato ultimo utente/nessun utente selezionato

        // Se selezionato altro utente
        default:
          // Seleziono prossimo utente
          IndiceUtenteSelezionato++;
          break;    // Chiusura case nessun utente selezionato
      }    // Chiusura switch seleziono utente selezionato

      // Se trovato utente con nome non nullo
      if (LeggiNomeUtente (IndiceUtenteSelezionato).length() != 0x00)
        // Blocco ciclo for verifico tutte le posizioni utente
        break;
    }    // Chiusura ciclo for verifico tutte le posizioni utente

    // Se non trovato utente con nome non nullo
    if (tmp == NumMaxNomiUtenti)
      // Seleziono nessun utente
      IndiceUtenteSelezionato = 0xFF;
  }    // Chiusura if premuto tasto 1

  // Se utente selezionato
  if (IndiceUtenteSelezionato != 0xFF) {
    // Leggo nome/peso utente
    NomeUtenteSelezionato = LeggiNomeUtente (IndiceUtenteSelezionato);
    PesoUtenteSelezionato = LeggiPesoUtente (IndiceUtenteSelezionato);
    // Calcolo lunghezza nome utente    
    LunghezzaNomeUtenteSelezionato = NomeUtenteSelezionato.length();
    // Seleziono lunghezza nome utente
    switch (LunghezzaNomeUtenteSelezionato) {
      case 0:
        // Indico nessun utente selezionato
        IndiceUtenteSelezionato = 0xFF;
        break;
      case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        LCDDisplay.clear();
        LCDDisplay.setCursor ((8 - LunghezzaNomeUtenteSelezionato) / 2, 0);
        LCDDisplay.print (NomeUtenteSelezionato);
        break;
      case 8:
        LCDDisplay.setCursor (0, 0);
        LCDDisplay.print (NomeUtenteSelezionato);
        break;
      default:
        if ((IndiceCarattere + 8) > LunghezzaNomeUtenteSelezionato)
          IndiceCarattere = 0;

        LCDDisplay.setCursor (0, 0);
        LCDDisplay.print (&NomeUtenteSelezionato[IndiceCarattere]);

        // Messaggio scorrevole
        IndiceCarattere++;
        if ((IndiceCarattere + 8) > LunghezzaNomeUtenteSelezionato)
          IndiceCarattere = 0;
        break;
    }    // Chiusura switch seleziono lunghezza nome utente
    LCDDisplay.setCursor (0, 1);
    LCDDisplay.print (PesoUtenteSelezionato / 1000);
    LCDDisplay.print ((PesoUtenteSelezionato % 1000) / 100);
    LCDDisplay.print ((PesoUtenteSelezionato % 100) / 10);
    LCDDisplay.print (".");
    LCDDisplay.print (PesoUtenteSelezionato % 10);    
    LCDDisplay.print (" Kg");

    // Se premuto interruttore (utente salito)
    if (PulsantePremuto (PinInterruttore) == 1) {
      LCDDisplay.setCursor (0, 1);
      LCDDisplay.print ("..... Kg");

      // Leggo valore analogico peso
      for (;;) {
        // Attesa
        delay (500);
        // Eseguo prima lettura peso
        ValoreSensorePesoTMP1 = analogRead (PinVPeso);
        delay (125);
        ValoreSensorePesoTMP2 = analogRead (PinVPeso);
        delay (125);
        ValoreSensorePesoTMP3 = analogRead (PinVPeso);
        delay (125);
        ValoreSensorePesoTMP4 = analogRead (PinVPeso);
        delay (125);
        ValoreSensorePeso1 = ((ValoreSensorePesoTMP1 + ValoreSensorePesoTMP2 + ValoreSensorePesoTMP3 + ValoreSensorePesoTMP4) / 4);

        // Attesa
        delay (500);
        // Eseguo seconda lettura peso
        ValoreSensorePesoTMP1 = analogRead (PinVPeso);
        delay (125);
        ValoreSensorePesoTMP2 = analogRead (PinVPeso);
        delay (125);
        ValoreSensorePesoTMP3 = analogRead (PinVPeso);
        delay (125);
        ValoreSensorePesoTMP4 = analogRead (PinVPeso);
        delay (125);
        ValoreSensorePeso2 = ((ValoreSensorePesoTMP1 + ValoreSensorePesoTMP2 + ValoreSensorePesoTMP3 + ValoreSensorePesoTMP4) / 4);

        // Se peso stabilizzato
        if ((ValoreSensorePeso1 <= ValoreSensorePeso2) && ((ValoreSensorePeso2 - ValoreSensorePeso1) < (int) (AnalogDifferenzaPesoMAX)) ||
            (ValoreSensorePeso1 > ValoreSensorePeso2) && ((ValoreSensorePeso1 - ValoreSensorePeso2) < (int) (AnalogDifferenzaPesoMAX)))
          // Blocco ciclo for leggo valore analogico peso
          break;
      }    // Chiusura ciclo for leggo valore analogico peso

      // Calcolo peso utente
      PesoCalcolato = (int) (ValoreSensorePeso2 - CalibrazioneSensore);
      PesoCalcolato = (PesoCalcolato + (((int) (PesoCalcolato * (int) (10))) / (int) (62)));

//    68.1 KG
//    642   con calibrazione: 62 -> Veff = 580

      // Se peso valido
      if ((PesoCalcolato >= (int) (PesoMIN)) && (PesoCalcolato <= (int) (PesoMAX))) {
        // Memorizzo peso utente
        ScriviPesoUtente (IndiceUtenteSelezionato, PesoCalcolato);

        // Visualizzo peso calcolato
        LCDDisplay.setCursor (0, 1);
        LCDDisplay.print (PesoCalcolato / 1000);
        LCDDisplay.print ((PesoCalcolato % 1000) / 100);
        LCDDisplay.print ((PesoCalcolato % 100) / 10);
        LCDDisplay.print (".");
        LCDDisplay.print (PesoCalcolato % 10);    
        LCDDisplay.print (" Kg");

        // Richiedo pubblicazione        
        LCDDisplay.setCursor (0, 0);
        LCDDisplay.print ("Pubblic?");

        // Per massimo 5 secondi attendo pressione tasto 2
        for (tmp = 0; tmp < 10; tmp++) {
          // Se premuto tasto 2
          if (PulsantePremuto (PinPulsanteP2) == 1) {
            // Indico pubblicazione in corso     
            LCDDisplay.setCursor (0, 0);
            LCDDisplay.print ("Pubblic.");
            LCDDisplay.setCursor (0, 1);
            LCDDisplay.print ("  wait  ");

            // Eseguo pubblicazione
            for (tmp = 0; tmp < NomeUtenteSelezionato.length(); tmp++) {
              newURL[76 + tmp] = NomeUtenteSelezionato.charAt(tmp);
              if (newURL[76 + tmp] == ' ')
                newURL[76 + tmp] = '+';
            }
            newURL[124] = ((PesoCalcolato / 1000) + 0x30);
            newURL[125] = (((PesoCalcolato % 1000) / 100) + 0x30);      
            newURL[126] = (((PesoCalcolato % 100) / 10) + 0x30);      
            newURL[128] = ((PesoCalcolato % 10) + 0x30);      
            googlePublish.setURL(newURL);
            googlePublish.submit();    
            delay (500);
            // Blocco ciclo for
            break;
          }
          delay (500);          
        }    // Chiusura ciclo for per massimo 5 secondi attendo pressione tasto 2
/*
        // Se SD rilevata
        if (presenzaSDCard == true) {
          // Verifico/Creo directory BilanciaWiFi
          if (!(SD.exists ("BilanciaWiFi")))
            SD.mkdir ("BilanciaWiFi");

          // Memorizzo il peso su file
          File filePeso;
          // Apro il file in scrittura
          char nomeFilePeso[50] = {"BilanciaWiFi/"};
          for (tmp = 0; tmp < NomeUtenteSelezionato.length(); tmp++) {
            charTmp[0] = NomeUtenteSelezionato.charAt(tmp);
            strcat (nomeFilePeso, charTmp);
          }
          strcat (nomeFilePeso, ".txt");          
          filePeso = SD.open (nomeFilePeso, FILE_WRITE);

          // Se apertura file OK
          if (filePeso) {
            // Memorizzo il peso
            filePeso.print ((PesoCalcolato / 1000) + 0x30);
            filePeso.print (((PesoCalcolato % 1000) / 100) + 0x30);
            filePeso.print (((PesoCalcolato % 100) / 10) + 0x30);
            filePeso.print (".");
            filePeso.print ((PesoCalcolato % 10) + 0x30);
            filePeso.print (" Kg");
            // Chiudo il file:
            filePeso.close();
          }
        }
*/

        LCDDisplay.setCursor (0, 0);
        LCDDisplay.print ("  Step  ");
        LCDDisplay.setCursor (0, 1);
        LCDDisplay.print ("  off   ");

        // Attendo utente scende dalla bilancia
        for (;;) {
          // Se non premuto interruttore (utente non salito)
          if (PulsantePremuto (PinInterruttore) == 0)
            break;
        }
      }    // Chiusura if peso valido
    }    // Chiusura if premuto interruttore (utente salito)
  }    // Chiusura if utente selezionato

  // Se nessun utente selezionato
  else {
    LCDDisplay.setCursor (0, 0);
    LCDDisplay.print (" Chose  ");
    LCDDisplay.setCursor (0, 1);
    LCDDisplay.print (" user   ");
  }    // Chiusura if nessun utente selezionato
}

// Funzione Gestione Seriale
void GestioneSeriale() {
  String comandoRicevutoString = "";
  int numeroUtenteRicevuto;
  String nomeUtenteRicevuto = "";

  // Se ricevuti dati dalla porta seriale
  if (Serial.available()) {
    // Attendo tutti i dati
    delay (250);

    // Ricevo i dati
    while (Serial.available())
      comandoRicevutoString += (char) (Serial.read());

    // Invio comando ricevuto    
    Serial.println (comandoRicevutoString);

    // Se ricevuti almeno 15 caratteri
    if (comandoRicevutoString.length() >= 15) {
      // Se ricevuto comando programmazione nome utente (NOME_UTENTE_xx=)USER_NAME_01=Boris
      if ((comandoRicevutoString.substring (0, 12).equals("P_USER_NAME_")) &&
          (isdigit(comandoRicevutoString.charAt (12))) &&
          (isdigit(comandoRicevutoString.charAt (13)))) {
        // Estraggo numero utente ricevuto
        numeroUtenteRicevuto = (((comandoRicevutoString.charAt (12) - 0x30) * 10) +
                                (comandoRicevutoString.charAt (13) - 0x30));
        // Se ricevuto numero utente corretto
        if ((numeroUtenteRicevuto >= 1) && (numeroUtenteRicevuto <= NumMaxNomiUtenti)) {
          // Estraggo nome utente
          nomeUtenteRicevuto = comandoRicevutoString.substring (15);
          // Se nome troppo lungo
          if (nomeUtenteRicevuto.length() > DimensioneNomeUtenteEEPROMADD)
            // Tronco il nome
            nomeUtenteRicevuto = nomeUtenteRicevuto.substring (0, DimensioneNomeUtenteEEPROMADD);

          // Memorizzo il nome
          ScriviNomeUtente (numeroUtenteRicevuto - 1, nomeUtenteRicevuto);
          // Azzero il relativo peso
          AzzeraPesoUtente (numeroUtenteRicevuto - 1);
          // Indico OK
          Serial.println ("OK");
          // Invio su  porta seriale lo stato utenti
          InviaProgrammazioneUtenti();
          // Termino funzione
          return;
        }
      }
    }  

    // Indico errore
    Serial.println ("FAULT");
    // Termino funzione
    return;
  }
}

// Invia su  porta seriale lo stato utenti
void InviaProgrammazioneUtenti() {
  for (int numeroUtente = 0; numeroUtente < NumMaxNomiUtenti; numeroUtente++) {
    Serial.print ("Us. ");
    Serial.print ((numeroUtente + 1) / 10);
    Serial.print ((numeroUtente + 1) % 10);
    Serial.print (": ");
    Serial.println (LeggiNomeUtente (numeroUtente));
  }
}

// Funzione Gestione WiServer
void GestioneWiServer() {
  // Gestione WiServer
  WiServer.server_task();
}

// Gestione diverse risposte provenienti dal WEB
void Gestione_Risposte_Web (char* data, int len) {

  // Print the data returned by the server
  // Note that the data is not null-terminated, may be broken up into smaller packets, and 
  // includes the HTTP header. 
  while (len-- > 0) {
    Serial.print(*(data++));
  } 

}

// Scrive il nome di un utente
// INPUT:   Posizione utente (0,..,9)
//          Nome utente in formato stringa
// OUTPUT:  -
// Note:    -
void ScriviNomeUtente (int NomePosition, String NomeUtente) {
  // Azzero nome utente selezionato
  AzzeraNomeUtente (NomePosition);

  // Scrivo i caratteri nome utente selezionato
  for (int tmp = 0; tmp < NomeUtente.length(); tmp++)
    EEPROM.write (StartNomiUtentiEEPROMADD + tmp +
                  (NomePosition * DimensioneNomeUtenteEEPROMADD), NomeUtente.charAt(tmp));
}

// Legge il nome di un utente
// INPUT:   Posizione utente (0,..,9)
// OUTPUT:  Nome utente in formato stringa
// Note:    -
String LeggiNomeUtente (int NomePosition) {
  String NomeUtente = "";
  char NomeUtenteChar;

  // Leggo i caratteri nome utente selezionato
  for (int tmp = 0; tmp < DimensioneNomeUtenteEEPROMADD; tmp++) {
    // Leggo singolo carattere
    NomeUtenteChar = EEPROM.read (StartNomiUtentiEEPROMADD + tmp +
                                  (NomePosition * DimensioneNomeUtenteEEPROMADD));

    // Se trovato carattere fine nome
    if (NomeUtenteChar == 0x00)
      // Blocco ciclo for leggo i caratteri nome utente selezionato
      break;

    // Accodo carattere letto
    NomeUtente = NomeUtente + NomeUtenteChar;
  }

  // Ritorno il nome
  return (NomeUtente);
}

// Azzera il nome di un utente
// INPUT:   Posizione utente (0,..,9)
// OUTPUT:  -
// Note:    -
void AzzeraNomeUtente (int NomePosition) {
  // Azzero caratteri nome utente selezionato
  for (int tmp = 0; tmp < DimensioneNomeUtenteEEPROMADD; tmp++)
    EEPROM.write (StartNomiUtentiEEPROMADD + tmp +
                  (NomePosition * DimensioneNomeUtenteEEPROMADD), 0); 
}

// Scrive il peso di un utente
// INPUT:   Posizione utente (0,..,9)
//          Peso utente
// OUTPUT:  -
// Note:    -
void ScriviPesoUtente (int PesoPosition, int PesoUtente) {
  // Memorizzo peso nome utente
  EEPROM.write (StartPesiUtentiEEPROMADD + 
                (PesoPosition * DimensionePesoUtenteEEPROMADD), (byte) (PesoUtente >> 8));
  EEPROM.write (StartPesiUtentiEEPROMADD + 1 +
                (PesoPosition * DimensionePesoUtenteEEPROMADD), (byte) (PesoUtente & 0x00FF));
}

// Legge il peso di un utente
// INPUT:   Posizione utente (0,..,9)
// OUTPUT:  Peso utente
// Note:    -
int LeggiPesoUtente (int PesoPosition) {
  // Ritorno il peso
  return (((int) (EEPROM.read (StartPesiUtentiEEPROMADD +
                               (PesoPosition * DimensionePesoUtenteEEPROMADD))) << 8) +
           (int) (EEPROM.read (StartPesiUtentiEEPROMADD + 1 +
                               (PesoPosition * DimensionePesoUtenteEEPROMADD))));
}

// Azzera il peso di un utente
// INPUT:   Posizione utente (0,..,9)
// OUTPUT:  -
// Note:    -
void AzzeraPesoUtente (int PesoPosition) {
  // Azzero peso nome utente
  ScriviPesoUtente (PesoPosition, 0);
}

// Inizializza EEPROM scheda
// INPUT:   -
// OUTPUT:  -
// Note:    -
void InizializzaEEPROM() {
  // Azzero i nomi/pesi di tutti gli utenti
  for (int tmp = 0; tmp < NumMaxNomiUtenti; tmp++) {
    AzzeraNomeUtente (tmp);
    AzzeraPesoUtente (tmp);
  }    
}

// Verifica lo stato di un pulsante
// INPUT:   Pin pulsante
// OUTPUT:  Stato pulsante    0 -> pulsante non premuto
//                            1 -> pulsante premuto
// Note:    -
int PulsantePremuto (int PinPulsante) {
  if (digitalRead (PinPulsante) == LOW)
    return (1);
  else
    return (0);
}

 

Install the WiShield libraries


To work properly, the Wifi shield requires specific libraries that must be installed in the Arduino IDE used to compile the sources so you’ll need to put these libraries in the Arduino libraries path.


The library supports multiple operating modes (APP_WEBSERVER, APP_WEBCLIENT, APP_SOCKAPP, APP_UDPAPP and APP_WISERVER).

The default value is APP_WEBSERVER, which runs on most Arduino systems but has several limitations. The main limitation is that it can’t function both as a client and server simultaneously.


It is therefore recommended the APP_WISERVER (in the library named “WiServer.h“) which allows the Arduino shield equipped with Wi-Fi to be configured and operated either as a Web Server as a Web Client.


In the first case, you can serve connection requests from external web clients and send HTML pages in response, in the second it will be possible to connect to a web server and send GET or POST requests.


To configure the WiShield library as APP_WISERVER you must open the apps-conf.h file, comment the “#define“ APP_WEBSERVER row and uncomment the “#define” of APP_WISERVER row.


Something like:


/ / # define APP_WEBSERVER

/ / # define APP_WEBCLIENT

/ / # define APP_SOCKAPP

/ / # define APP_UDPAPP

# defineAPP_WISERVER


Configuring publishing

Performing data publication on Google Documents requires three distinct steps:


  1. Configuring Wi-Fi network access;
  2. Creating a Google Docs form module: each module is characterized by an identifying 34 characters string – FormKey) and each field is characterized by an identification number (called Entry).
  3. Inserting the FormKey / Entry in the Arduino software.



Configuring network parameters

First you must configure and update the IP address, Subnet Mask, Gateway IP and Network SSID, then select the encryption mode and change password information for your network. Save all, compile and run the upload Software tab.

Creating the Google  module doc

Create a form on Google Docs, modify the form with two fields (username and weight, both of type string) and save the job. (the result is something like the one shown in Figure). In our case, we left the default file name and called the two fields “User Name” and “User weight”

take note of this key string because then it will be inserted in the Arduino software: as you can see from the picture, the link shows the form key assigned to the module (in this example, the link is: https://docs.google.com/spreadsheet/viewform?formkey=dDFPcWhxNlZxMEpnUnhNdE5fT1lDcWc6MQ which implies that the form assigned key is “dDFPcWhxNlZxMEpnUnhNdE5fT1lDcWc6MQ”);

 

Clicking on the link will open a new page that shows the data entry form: within this form text fields are marked with “entry.0.single“, “entry.1.single“, etc … (basically with an integer id)

 To see which number has been assigned to our fields you need to display the HTML source of the form (the result is something like the one shown in this Figure).

You can easily find the ID numbers assigned to different fields (in our example “entry.0.single” is the “Name” and “entry.1.single” is the “weight“).

Take note of this information because it will be included in the source Arduino as well.

Formkey / entry

Once you have created the form, the Arduino source will be configured so that it is compatible with the form you created.

A variable is defined in Arduino source named newURL[]: the variable is initialized with a standard format then modified to perform publication (refer to Figure 11 to identify it in the code).


Replace the default values with those obtained at the time of the creation of the form, compile and download it to the Arduino board.

 

 

 

How to program user names

The configuration of user names can be made via serial port and Serial Monitor. To program it, connect to the board (via USB cable) and open the Arduino Serial Monitor. As a first step the card sends a summary of the current configuration.


To program a new user name you must send a string in the format “P_USER_NAME_xx = User Name” with xx between 01 and 10 ID (put an empty string to delete the selected user.) If all the posted information is correct, this is confirmed by the message “Ok” otherwise “Fault”.

 

Using the scale


The scale software is able to distinguish up to 10 users (each identified by its name) and, for each one, it stores the last measured weight.


If you want to clear the memory (which we recommend at first use) is sufficient to hold down either of the two buttons (the display indicates the operation with “EEP init in progress”).

Later, you can configure names following the procedure described in the “Programming user names” section.


As the next step the Web management interface will start and the system will enter its normal operation. The user selection is done by pressing button P1.


Going over the scale starts the weighing procedure (lasting several seconds): weight is displayed and stored and the scale asks for publishing on the web: by pressing P2 the operation is performed.

Drive a DC Motor With Arduino DUE

 

We are proud to show you a tutorial about using an Arduino Motor Shield with the  Arduino Due. This example shows the simplest thing you can do: driving a DC motor forward and backwards.

Read on the [tutorial]

Arduino Blog 31 Oct 18:59

Review: Gooligum Electronics PIC Training Course and Development Board

Introduction

[Updated 18/06/2013]

There are many types of microcontrollers on the market, and it would be fair to say one of the two most popular types is the Microchip PIC series. The PICs are great as there is a huge range of microcontrollers available across a broad range of prices. However learning how to get started with the PIC platform isn’t exactly simple. Not that we expect it to be, however a soft start is always better. There are some older books, however they can cost more than $100 – and are generally outdated. So where do you start?

It is with this problem in mind that led fellow Australian David Meiklejohn to develop and offer his PIC Training Course and Development Board to the marketplace via his company Gooligum Electronics.

In his words:

There is plenty of material available on PICs, which can make it daunting to get started.  And some of the available material is dated, originally developed before modern “flash” PICs were available, or based on older devices that are no longer the best choice for new designs.  Our approach is to introduce PIC programming and design in easy stages, based on a solid grounding in theory, creating a set of building blocks and techniques and giving you the confidence to draw on as we move up to more complex designs.

So in this article we’ll examine David’s course package. First of all, let’s look at the development board and inclusions. Almost everything you will need to complete all the lessons is included in the package, including the following PIC microcontrollers:

You can choose to purchase the board in kit form or pre-assembled. If you enjoy soldering, save the money and get the kit – it’s simple to assemble and a nice way to spend a few hours with a soldering iron.

Although the board includes all the electronic components and PICs – you will need are a computer capable of running Microchip MPLAB software, a Microchip PICkit3 (or -2) programming device and an IC extractor. If you’re building the kit, a typical soldering iron and so on will be required. Being the  ultra-paranoid type, I bought a couple extra of each PIC to have as spares, however none were damaged in my experimenting. Just use common-sense when handling the PICs and you will be fine.

Assembly

Putting the kit board together wasn’t difficult at all. There isn’t any surface-mount parts to worry about, and the PCB is silk-screened very well:

The rest of the parts are shipped in antistatic bags, appropriately labelled and protected:

Assembly was straight forward, just start with the low-profile parts and work your way up. The assembly guide is useful to help with component placement. After working at a normal pace, it was ready in just over an hour:

The Hardware

Once assembled (or you’ve opened the packaging) the various sections of the board are obvious and clearly labelled – as they should be for an educational board. You will notice a large amount of jumper headers – they are required to bridge in and out various LEDs, select various input methods and so on. A large amount of jumper shunts is included with the board.

It might appear a little disconcerting at first, but all is revealed and explained as you progress through the lessons. The board has decent rubber feet, and is powered either by the PICkit3 programmer, or a regulated DC power source between 5 and 6V DC, such as from a plug-pack if you want to operate your board away from a PC.

However there is a wide range of functions, input and output devices on the board – and an adjustable oscillator, as shown in the following diagram:

The Lessons

There is some assumed knowledge, which is a reasonable understanding of basic electronics, some computer and mathematical savvy and the C programming language.

You can view the first group of lessons for free on the kit website, and these are included along with the additional lessons in the included CDROM. They’re in .pdf format and easy to read. The CDROM also includes all the code so you don’t have to transcribe it from the lessons. Students start with an absolute introduction to the system, and first learn how to program in assembly language in the first group of tutorials, followed by C in the second set.

This is great as you learn about the microcontroller itself, and basically start from the bottom. Although it’s no secret I enjoy using the Arduino system – it really does hide a lot of the actual hardware knowledge away from the end user which won’t be learned. With David’s system – you will learn.

If you scroll down to the bottom of this page, you can review the tutorial summaries. Finally here’s a quick demonstration of the 7-segment displays in action:

Update – 18/06/2013

David has continued publishing more tutorials for his customers every few months – including such topics as the EEPROM and pulse-width modulation. As part of the expanded lessons you can also get a pack which allows experimenting with electric motors that includes a small DC motor, the TI SN75441 h-bridge IC, N-channel and P-channel MOSFETS and more:

So after the initial purchase, you won’t be left on your own. Kudos to David for continuing to support and develop more material for his customers.

Where to from here? 

Once you run through all the tutorials, and feel confident with your knowledge, the world of Microchip PIC will be open to you. Plus you now have a great development board for prototyping with 6 to 14-pin PIC microcontrollers. Don’t forget all the pins are brought out to the row of sockets next to the solderless breadboard, so general prototyping is a breeze.

Conclusion

For those who have mastered basic electronics, and have some C or C-like programming experience from using other development environments or PCs – this package is perfect for getting started with the Microchip PIC environment. Plus you’ll learn about assembly language – which is a good thing. I genuinely recommend this to anyone who wants to learn about PIC and/or move into more advanced microcontroller work. And as the entire package is cheaper than some books –  you can’t go wrong. The training course is available directly from the Gooligum website.

Disclaimer – The Baseline and Mid-Range PIC Training Course and Development Board was a promotional consideration from Gooligum Electronics.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Review: Gooligum Electronics PIC Training Course and Development Board appeared first on tronixstuff.

IKEA SMS lamp with GSM shield

-->-->-->-->

 

 

 

We create a lamp controlled by SMS using a GSM shield, a RGB shield and a Arduino UNO.
Due to the simplicity of these boards, simply plug one over the other and connect a strip led to have a lighting effect.
Then sending normal text messages from any phone, you can turn on and choose the color to set.

The scketch check the text of the received message, if the SMS contains a character, it follows on the corresponding color.
It ‘also provided a fader functions can be called with the character F

This is the list commands:
R to set RED
G to set GREEN
B to set BLUE
Y to set YELLOW
O to set ORANGE
P to set PURPLE
W to set WHITE
F to set the fader function

This is just an example of the possible applications of the GSM / GPRS shield.
You can for example control the home lighting with a simple text message, or receive an SMS in case of alarm.
In addition, the SIM900 has the capacity to also decode DTMF tones, so you can call this in the sim GSM shield and switch loads directly from the telephone keypad.

The complete library it contains many other functions through which you can make calls, connect to the Internet, send and receive SMS.

This is the simple firmware in Arduino.

 

//GSM Shield for Arduino
//www.open-electronics.org
//this code is based on the example of Arduino Labs

#include "SIM900.h"
#include "sms.h"
#include "SoftwareSerial.h"
#include "sms.h"
SMSGSM sms;
int red = 10;    // RED LED connected to PWM pin 3
int green = 5;    // GREEN LED connected to PWM pin 5
int blue = 6;    // BLUE LED connected to PWM pin 6
int r=50; int g=100; int b=150;
int rup; int gup; int bup;

boolean started=false;
char smsbuffer[160];
char n[20];
int fader=1;
int inc=10;

void setup() 
{
  //Serial connection.
  Serial.begin(9600);
  Serial.println("GSM Shield testing.");
  //Start configuration of shield with baudrate.
  if (gsm.begin(2400)){
    Serial.println("\nstatus=READY");
    started=true;  
  }
  else Serial.println("\nstatus=IDLE");
  if(started){
    delsms();
  }

};

void loop() 
{
  int pos=0;
  //Serial.println("Loop");
  if(started){
    pos=sms.IsSMSPresent(SMS_ALL);
    if(pos){
      Serial.println("IsSMSPresent at pos ");
      Serial.println(pos); 
      sms.GetSMS(pos,n,smsbuffer,100);
        Serial.println(n);
        Serial.println(smsbuffer);
        if(!strcmp(smsbuffer,"R")){
          Serial.println("RED");
          r=255;
          g=0;
          b=0;
        }      
        if(!strcmp(smsbuffer,"G")){
          Serial.println("GREEN");
          r=0;
          g=255;
          b=0;
        }    
        if(!strcmp(smsbuffer,"B")){
          Serial.println("BLUE");
          r=0;
          g=0;
          b=255;
        }  
        if(!strcmp(smsbuffer,"P")){
          Serial.println("PURPLE");
          r=255;
          g=0;
          b=255;
        }  
        if(!strcmp(smsbuffer,"Y")){
          Serial.println("YELLOW");
          r=255;
          g=255;
          b=0;
        }  
        if(!strcmp(smsbuffer,"O")){
          Serial.println("ORANGE");
          r=255;
          g=165;
          b=0;
        }  
        if(!strcmp(smsbuffer,"W")){
          Serial.println("WHITE");
          r=255;
          g=255;
          b=255;
        }  
        if(!strcmp(smsbuffer,"F")){
          Serial.println("FADER");
          fader=1;
          r=50; g=100; b=150;
        }
        else
        {
          fader=0;
        }  
        rgb(r, g, b);
        delsms();

    }
    if(fader){
      funcfader();
    }

  }
};

void delsms(){
  Serial.println("delsms");
  for (int i=0; i<10; i++){  //do it max 10 times
      int pos=sms.IsSMSPresent(SMS_ALL);
      if (pos!=0){
        Serial.print("\nFind SMS at the pos ");
        Serial.println(pos); 
        if (sms.DeleteSMS(pos)==1){    
          Serial.print("\nDeleted SMS at the pos ");
          Serial.println(pos);      
        }
        else
        {
          Serial.print("\nCant del SMS at the pos ");
          Serial.println(pos);         
        }
      }
    }

}

void funcfader(){
    if (rup==1){r+=1;}
    else{r-=1;}
    if (r>=255){rup=0;}
    if (r<=0){rup=1;}

    if (gup==1){g+=1;}
    else{g-=1;}
    if (g>=255){gup=0;}
    if (g<=0){gup=1;}

    if (bup==1){b+=1;}
    else{b-=1;}
    if (b>=255){bup=0;}
    if (b<=0){bup=1;}  
    rgb(r, g, b);
}

void rgb(int r, int g, int b)
{
  if (r>255) r=255;
  if (g>255) g=255;
  if (b>255) b=255;
  if (r<0) r=0;
  if (g<0) g=0;
  if (b<0) b=0;

  analogWrite(red, r); 
  analogWrite(green, g); 
  analogWrite(blue, b);   
}
-->-->-->-->-->-->
-->-->