martedì 22 maggio 2012
WebServer su Arduino Ethernet
Un altro modo di presentare i dati dei sensori differente dall'UDP e' quello di mostrarli direttamente su un browser (senza dover quindi scrivere due applicazioni differenti ai due lati del cavo)
Un primo tentativo di installare un WebServer sull'Arduino Ethernet e' andato buca ma dopo le modifiche al file w5100.h effettuato in questo post tutto ha funzionato in modo corretto
Lo sketch impiegato e' quello presente negli esempi dell'Arduino (sotto File/Examples/Ethernet/Webserver) ed e' stato leggermente modificato per mostrare a video il tempo passato dall'accensione della scheda e con un tag html che permette il refresh automatico della pagina ogni secondo
(i valori letti sulle porte analogiche sono random in quanto al momento della prova non c'era nessun sensore connesso)
-----------------------------
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 2 };
Server server(80);
unsigned long tempo;
void setup()
{
Ethernet.begin(mac, ip);
server.begin();
}
void loop()
{
Client client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
//gestisce il refresh automatico della pagina per aggiornare
//al valore dei sensori
client.println("<meta http-equiv=\"refresh\" content=\"1\">");
tempo = round(millis()/1000);
client.print("Tempo trascorso (sec): ");
client.print(tempo);
client.print("</br></br>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(analogRead(analogChannel));
client.println("<br />");
}
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop();
}
}
Un primo tentativo di installare un WebServer sull'Arduino Ethernet e' andato buca ma dopo le modifiche al file w5100.h effettuato in questo post tutto ha funzionato in modo corretto
Lo sketch impiegato e' quello presente negli esempi dell'Arduino (sotto File/Examples/Ethernet/Webserver) ed e' stato leggermente modificato per mostrare a video il tempo passato dall'accensione della scheda e con un tag html che permette il refresh automatico della pagina ogni secondo
-----------------------------
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 2 };
Server server(80);
unsigned long tempo;
void setup()
{
Ethernet.begin(mac, ip);
server.begin();
}
void loop()
{
Client client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
//gestisce il refresh automatico della pagina per aggiornare
//al valore dei sensori
client.println("<meta http-equiv=\"refresh\" content=\"1\">");
tempo = round(millis()/1000);
client.print("Tempo trascorso (sec): ");
client.print(tempo);
client.print("</br></br>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(analogRead(analogChannel));
client.println("<br />");
}
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop();
}
}
lunedì 21 maggio 2012
Modem Analogici
Alcuni modem per linea analogica (nessuno e' mai stato usato da me prima di entrare nella collezione ma di fatto avevo un Aceex 2400 ed uno US Robotics Sposter 14.4K con cui andavo a giro per le BBS)
Sono ovviamente tutti seriali con porta DB25
Aceex 1200/2400/9600 |
US Robotics 56 K |
USR Robotics Sporster Voice 33.6k |
UDP tra Arduino e PC
Questo test e' per verificare lo scambio dati tra Arduino Ethernet e PC mediante pacchetti UDP (Arduino invia e PC riceve)
Da notare che l'Arduino funziona bene anche con una normale pila a 9V ricaricabile ed un cavo cross
Il Pc e' impostato come 192.168.1.120 ed ascolta su porta 5005
L'Arduino e' impostata come 192.168.1.2
Script Python per ricevere i dati
--------------------------------------------------------------------
import socket
UDP_IP="192.168.1.120"
UDP_PORT=5005
sock = socket.socket( socket.AF_INET, # Internet
socket.SOCK_DGRAM ) # UDP
sock.bind( (UDP_IP,UDP_PORT) )
while True:
data, addr = sock.recvfrom( 1024 ) # buffer size is 1024 bytes
print "Ricevuto: ", data
--------------------------------------------------------------------
Sketch Arduino per inviare i dati
--------------------------------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {192,168,1,2};
byte remote_ip[] = {192,168,1,120};
unsigned int remote_port = 5005;
char sendBuffer [] = "Luca\0";
unsigned int sent=0;
int contatore = 0;
void setup() {
Ethernet.begin(mac,ip);
Udp.begin(8008);
}
void loop() {
contatore = contatore + 1;
dtostrf(contatore,4,0,sendBuffer);
sent=Udp.sendPacket(sendBuffer, remote_ip, remote_port);
delay(500);
}
--------------------------------------------------------------------
ATTENZIONE:
con le ultime due versioni del software Arduino (0.23 e 1.0) esiste un bug nella gestione di UDP che genera dei pacchetti pieni di spazzatura.
Per risolvere il problema si deve individuare il file w5100.h che si trova in /libraries/Ethernet/Utility e modificarlo secondo quanto riportato da questo post (vedi al termine del post)
Il problema dovrebbe risultare risolto nella versione 1.0.1 di prossima uscita
Da notare che l'Arduino funziona bene anche con una normale pila a 9V ricaricabile ed un cavo cross
Il Pc e' impostato come 192.168.1.120 ed ascolta su porta 5005
L'Arduino e' impostata come 192.168.1.2
Script Python per ricevere i dati
--------------------------------------------------------------------
import socket
UDP_IP="192.168.1.120"
UDP_PORT=5005
sock = socket.socket( socket.AF_INET, # Internet
socket.SOCK_DGRAM ) # UDP
sock.bind( (UDP_IP,UDP_PORT) )
while True:
data, addr = sock.recvfrom( 1024 ) # buffer size is 1024 bytes
print "Ricevuto: ", data
--------------------------------------------------------------------
Sketch Arduino per inviare i dati
--------------------------------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {192,168,1,2};
byte remote_ip[] = {192,168,1,120};
unsigned int remote_port = 5005;
char sendBuffer [] = "Luca\0";
unsigned int sent=0;
int contatore = 0;
void setup() {
Ethernet.begin(mac,ip);
Udp.begin(8008);
}
void loop() {
contatore = contatore + 1;
dtostrf(contatore,4,0,sendBuffer);
sent=Udp.sendPacket(sendBuffer, remote_ip, remote_port);
delay(500);
}
--------------------------------------------------------------------
ATTENZIONE:
con le ultime due versioni del software Arduino (0.23 e 1.0) esiste un bug nella gestione di UDP che genera dei pacchetti pieni di spazzatura.
Per risolvere il problema si deve individuare il file w5100.h che si trova in /libraries/Ethernet/Utility e modificarlo secondo quanto riportato da questo post (vedi al termine del post)
Il problema dovrebbe risultare risolto nella versione 1.0.1 di prossima uscita
venerdì 18 maggio 2012
Bussola Pitch Roll ed Accelerometro
Ad integrazione del post precedente si possono leggere i valori di accelerazione triassiale coil seguente sketch
---------------------------------
#include <Wire.h>
#define ADDRESS 0x60 // Defines address of CMPS10
void setup(){
Wire.begin(); // Conects I2C
Serial.begin(9600);
}
void loop(){
byte highByte, lowByte, fine;
char pitch, roll;
int bearing;
byte high_x,low_x,high_y,low_y,high_z,low_z;
int acc_x,acc_y,acc_z;
Wire.beginTransmission(ADDRESS); //starts communication with CMPS10
Wire.send(2); //Sends the register we wish to start reading from
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 4); // Request 4 bytes from CMPS10
while(Wire.available() < 4); // Wait for bytes to become available
highByte = Wire.receive();
lowByte = Wire.receive();
pitch = Wire.receive();
roll = Wire.receive();
bearing = ((highByte<<8)+lowByte)/10; // Calculate full bearing
fine = ((highByte<<8)+lowByte)%10; // Calculate decimal place of bearing
display_data(bearing, fine, pitch, roll); // manda i dati alla seriale
Wire.beginTransmission(ADDRESS); //inizia lettura accelerometro
Wire.send(16);
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 6); // Richiede i 6 byte dell'accelerazione
while(Wire.available() < 6);
high_x = Wire.receive();
low_x = Wire.receive();
high_y = Wire.receive();
low_y = Wire.receive();
high_z = Wire.receive();
low_z = Wire.receive();
acc_x = ((high_x<<8)+low_x); // Calcola accel_x
acc_y = ((high_y<<8)+low_y); // Calcola accel_y
acc_z = ((high_z<<8)+low_z); // Calcola accel_z
display_acc(acc_x,acc_y,acc_z);
delay(1000);
}
void display_data(int b, int f, int p, int r){
Serial.print("Bearing = ");
Serial.print(b);
Serial.print(".");
Serial.println(f);
Serial.print("Pitch = ");
Serial.println(p);
Serial.print("Roll = ");
Serial.println(r);
}
void display_acc(int x, int y, int z){ // manda a stampa le accelerazioni
Serial.print("Acc.X = ");
Serial.println(x);
Serial.print("Acc.Y = ");
Serial.println(y);
Serial.print("Acc.Z = ");
Serial.println(z);
}
---------------------------------
#include <Wire.h>
#define ADDRESS 0x60 // Defines address of CMPS10
void setup(){
Wire.begin(); // Conects I2C
Serial.begin(9600);
}
void loop(){
byte highByte, lowByte, fine;
char pitch, roll;
int bearing;
byte high_x,low_x,high_y,low_y,high_z,low_z;
int acc_x,acc_y,acc_z;
Wire.beginTransmission(ADDRESS); //starts communication with CMPS10
Wire.send(2); //Sends the register we wish to start reading from
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 4); // Request 4 bytes from CMPS10
while(Wire.available() < 4); // Wait for bytes to become available
highByte = Wire.receive();
lowByte = Wire.receive();
pitch = Wire.receive();
roll = Wire.receive();
bearing = ((highByte<<8)+lowByte)/10; // Calculate full bearing
fine = ((highByte<<8)+lowByte)%10; // Calculate decimal place of bearing
display_data(bearing, fine, pitch, roll); // manda i dati alla seriale
Wire.beginTransmission(ADDRESS); //inizia lettura accelerometro
Wire.send(16);
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 6); // Richiede i 6 byte dell'accelerazione
while(Wire.available() < 6);
high_x = Wire.receive();
low_x = Wire.receive();
high_y = Wire.receive();
low_y = Wire.receive();
high_z = Wire.receive();
low_z = Wire.receive();
acc_x = ((high_x<<8)+low_x); // Calcola accel_x
acc_y = ((high_y<<8)+low_y); // Calcola accel_y
acc_z = ((high_z<<8)+low_z); // Calcola accel_z
display_acc(acc_x,acc_y,acc_z);
delay(1000);
}
void display_data(int b, int f, int p, int r){
Serial.print("Bearing = ");
Serial.print(b);
Serial.print(".");
Serial.println(f);
Serial.print("Pitch = ");
Serial.println(p);
Serial.print("Roll = ");
Serial.println(r);
}
void display_acc(int x, int y, int z){ // manda a stampa le accelerazioni
Serial.print("Acc.X = ");
Serial.println(x);
Serial.print("Acc.Y = ");
Serial.println(y);
Serial.print("Acc.Z = ");
Serial.println(z);
}
Bussola + Pitch + Roll
Ho sperimentato il sensore CMPS10 (in pratica una bussola con compensazione di inclinazione) che fornisce indicazioni anche sull'inclinazione degli assi di pitch e di roll
Il sensore costa una quarantina di euro ed ammette voltaggi di ingresso da 3.3 a 5 V (ottimo per l'Arduino) con un consumo di 25 mA. La risoluzione di 0.1 gradi con una accuratezza minima dell'1%.
La comunicazione puo' avvenire su interfaccia I2C, SPI e Seriale .. io sono andato sulla S2C
Questa e' la pedinatura dell'I2C..dato che il componente non riporta sigle sulla scheda e che si monta a testa all'ingiu' sulla breadboard mi sono fatto un adesivo con i nomi dei connettori per non sbagliare.
L'orientamento dell' heading della scheda e' verso sinistra ovvero il valore di angolo tra il Nord e la scheda viene letto rispetto al lato con i pin
ATTENZIONE : per funzionare correttamente il sensore deve essere messo con i pin e con gli integrati rivolti verso l'alto (non come in fotografia, nelle prove e' stata rigirara la breadboard) altrimenti la compensazione dell'inclinazione della bussola non funziona e risponde in modo causuale
La scheda di prova montata |
Per rendere piu' chiaro il montaggio della scheda riporto un disegno fatto con Fritzing
Lo skecth e' stato modificato rispetto a quello di esempio della ditta perche' sostanzialmente non funzionava per problemi sulla libreria Wire.h..cosi' funziona
------------
#include <Wire.h>
#define ADDRESS 0x60 // Defines address of CMPS10
void setup(){
Wire.begin(); // Conects I2C
Serial.begin(9600);
}
void loop(){
byte highByte, lowByte, fine; // highByte and lowByte store high and low bytes of the bearing and fine stores decimal place of bearing
char pitch, roll; // Stores pitch and roll values of CMPS10, chars are used because they support signed value
int bearing; // Stores full bearing
Wire.beginTransmission(ADDRESS); //starts communication with CMPS10
Wire.send(2); //Sends the register we wish to start reading from
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 4); // Request 4 bytes from CMPS10
while(Wire.available() < 4); // Wait for bytes to become available
highByte = Wire.receive();
lowByte = Wire.receive();
pitch = Wire.receive();
roll = Wire.receive();
bearing = ((highByte<<8)+lowByte)/10; // Calculate full bearing
fine = ((highByte<<8)+lowByte)%10; // Calculate decimal place of bearing
display_data(bearing, fine, pitch, roll); // Display data to the LCD03
delay(1000);
}
void display_data(int b, int f, int p, int r){ // pitch and roll (p, r) are recieved as ints instead oif bytes so that they will display corectly as signed values.
Serial.print("Bearing = "); // Display the full bearing and fine bearing seperated by a decimal poin on the LCD03
Serial.print(b);
Serial.print(".");
Serial.println(f);
Serial.print("Pitch = ");
Serial.println(p);
Serial.print("Roll = ");
Serial.println(r);
delay(1000);
}
#define ADDRESS 0x60 // Defines address of CMPS10
void setup(){
Wire.begin(); // Conects I2C
Serial.begin(9600);
}
void loop(){
byte highByte, lowByte, fine; // highByte and lowByte store high and low bytes of the bearing and fine stores decimal place of bearing
char pitch, roll; // Stores pitch and roll values of CMPS10, chars are used because they support signed value
int bearing; // Stores full bearing
Wire.beginTransmission(ADDRESS); //starts communication with CMPS10
Wire.send(2); //Sends the register we wish to start reading from
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 4); // Request 4 bytes from CMPS10
while(Wire.available() < 4); // Wait for bytes to become available
highByte = Wire.receive();
lowByte = Wire.receive();
pitch = Wire.receive();
roll = Wire.receive();
bearing = ((highByte<<8)+lowByte)/10; // Calculate full bearing
fine = ((highByte<<8)+lowByte)%10; // Calculate decimal place of bearing
display_data(bearing, fine, pitch, roll); // Display data to the LCD03
delay(1000);
}
void display_data(int b, int f, int p, int r){ // pitch and roll (p, r) are recieved as ints instead oif bytes so that they will display corectly as signed values.
Serial.print("Bearing = "); // Display the full bearing and fine bearing seperated by a decimal poin on the LCD03
Serial.print(b);
Serial.print(".");
Serial.println(f);
Serial.print("Pitch = ");
Serial.println(p);
Serial.print("Roll = ");
Serial.println(r);
delay(1000);
}
------------
Leggendo le specifiche mi sono accorto che nei registri da 16 a 21 (16-17 = X, 18-19 = Y, 20-21 = Z) sono inseriti i dati di accelerazione...potrebbe essere interessante
Per effettuare il reset ai valori di fabbrica si puo' usare la seguente procedura
----------------------------------------------------
#include <Wire.h>
#define deviceId 0x60 // Defines address of CMPS10
void setup(){
Wire.begin();
Wire.beginTransmission(deviceId);
Wire.send(22);
Wire.send(0x20);
Wire.endTransmission();
delay(100);
Wire.beginTransmission(deviceId);
Wire.send(22);
Wire.send(0x2A);
Wire.endTransmission();
delay(100);
Wire.beginTransmission(deviceId);
Wire.send(22);
Wire.send(0x60);
Wire.endTransmission();
}
void loop(){
}
----------------------------------------
#define deviceId 0x60 // Defines address of CMPS10
void setup(){
Wire.begin();
Wire.beginTransmission(deviceId);
Wire.send(22);
Wire.send(0x20);
Wire.endTransmission();
delay(100);
Wire.beginTransmission(deviceId);
Wire.send(22);
Wire.send(0x2A);
Wire.endTransmission();
delay(100);
Wire.beginTransmission(deviceId);
Wire.send(22);
Wire.send(0x60);
Wire.endTransmission();
}
void loop(){
}
----------------------------------------
giovedì 17 maggio 2012
Led
Non essendo molto pratico di elettronica mi manda nei pazzi anche un solo Led (quale sara' la maledetta polarita'??) per questo mi metto questo appunto
Il pin piu' lungo di un led corrisponde al polo positivo
Per evitare di bruciare un led e' necessario inserire una resistenza che nel caso di un led rosso puo' essere da 220 Ohm (ma fino ad un 1KOhm vanno bene)
Nel caso di uso con Arduino il Pin 13 digitale e' gia' provvisto di una resistenza interna per cui non e' necessario aggiungerne altre
Iscriviti a:
Post (Atom)
Cheshire Cat Ai
Cheshire Ai e' un progetto italiano che sta crescendo adesso Per provarlo si clona il progetto git clone https://github.com/cheshire-c...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...