La mia intenzione era quella di visualizzare sul display la temperatura...piu precisamente nel formato ad esempio -23.5 (i numeri al massimo possono essere quattro, quindi solo con un decimale per avere la possibilità di aggiungere il - nel caso la temperatura sia sotto lo zero)
Ho guardato due sketch di esempio per inviare i dati tramite I2C oppure tramite Seriale ma non sono riuscito a farlo funzionare correttamente. il sensore viene letto correttamente infatti tramite seriale sul pc compare la temperatura corretto ad esempio 23.50 .Solo che il passaggio successivo e cioé formattare il float per poi inviarlo al display non so come fare. Qualcusa sa come si può fare? Vi posto i codici. Grazie
invio dati tramite I2C
/*
11-2-2012
Spark Fun Electronics
Nathan Seidle
This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
Serial7Segment is an open source seven segment display.
This is example code that shows how to send data over I2C to the display.
Note: This code expects the display to be listening at the default I2C address. If your display is not at 0x71, you can
do a software or hardware reset. See the Wiki for more info:
http://github.com/sparkfun/Serial7SegmentDisplay/wiki/Special-Commands
To get this code to work, attached an Serial7Segment to an Arduino Uno using the following pins:
A5 to SCL
A4 to SDA
VIN to PWR
GND to GND
*/
#include <Wire.h>
#define DISPLAY_ADDRESS1 0x71 //This is the default address of the OpenSegment with both solder jumpers open
int cycles = 0;
void setup()
{
Wire.begin(); //Join the bus as master
Serial.begin(9600); //Start serial communication at 9600 for debug statements
Serial.println("OpenSegment Example Code");
//Send the reset command to the display - this forces the cursor to return to the beginning of the display
Wire.beginTransmission(DISPLAY_ADDRESS1);
Wire.write('v');
Wire.endTransmission();
}
void loop()
{
cycles++; //Counting cycles! Yay!
Serial.print("Cycle: ");
Serial.println(cycles);
i2cSendValue(cycles); //Send the four characters to the display
delay(1); //If we remove the slow debug statements, we need a very small delay to prevent flickering
}
//Given a number, i2cSendValue chops up an integer into four values and sends them out over I2C
void i2cSendValue(int tempCycles)
{
Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
Wire.write(tempCycles / 1000); //Send the left most digit
tempCycles %= 1000; //Now remove the left most digit from the number we want to display
Wire.write(tempCycles / 100);
tempCycles %= 100;
Wire.write(tempCycles / 10);
tempCycles %= 10;
Wire.write(tempCycles); //Send the right most digit
Wire.endTransmission(); //Stop I2C transmission
}
invio dati tramite Seriale
/*
9-23-2012
Spark Fun Electronics
Nathan Seidle
This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
Serial7Segment is an open source seven segment display.
This is example code that shows how to display basic numbers on the display.
Note: This code expects the display to be listening at 9600bps. If your display is not at 9600bps, you can
do a software or hardware reset. See the Wiki for more info:
http://github.com/sparkfun/Serial7SegmentDisplay/wiki/Special-Commands#wiki-baud
To get this code to work, attached an Serial7Segment to an Arduino Uno using the following pins:
Pin 8 on Uno (software serial TX) to RX on Serial7Segment
VIN to PWR
GND to GND
*/
#include <SoftwareSerial.h>
SoftwareSerial Serial7Segment(7, 8); //RX pin, TX pin
int cycles = 0;
void setup() {
Serial.begin(9600);
Serial.println("OpenSegment Example Code");
Serial7Segment.begin(9600); //Talk to the Serial7Segment at 9600 bps
Serial7Segment.write('v'); //Reset the display - this forces the cursor to return to the beginning of the display
}
void loop()
{
cycles++; //Counting cycles! Yay!
Serial.print("Cycle: ");
Serial.println(cycles);
char tempString[10]; //Used for sprintf
sprintf(tempString, "%4d", cycles); //Convert deciSecond into a string that is right adjusted
//sprintf(tempString, "%d", cycles); //Convert deciSecond into a string that is left adjusted (requires digit 1 command)
//sprintf(tempString, "%04d", cycles); //Convert deciSecond into a string with leading zeros
//sprintf(tempString, "%4X", cycles); //Count in HEX, right adjusted
//int negativeCycles = cycles * -1;
//sprintf(tempString, "%4d", negativeCycles); //Shows a negative sign infront of right adjusted number
//Note: This method works well as long as your number is less than or equal to 4 digits.
//14422 will cause the display to wrap (5 digits)
//-5766 will cause the display to wrap (5 digits)
//To fix this, send a 'v' character or look at how to control the digit placement
//https://github.com/sparkfun/Serial7SegmentDisplay/wiki/Basic-Usage#wiki-cursor
Serial7Segment.print(tempString); //Send serial string out the soft serial port to the S7S
delay(10);
}
A mio modesto parere, se non hai una lib per gestire i segmenti dei vari display, ti devi realizzare tu un protocollo di comunicazione; quello è un display a catodo comune con i sette sementi (e il dp) tutti in parallelo tra loro, di conseguenza devi usare il multiplexing. Cerca il "Micrologio" di Leo72, lì c'è un ottimo sw di esempio fatto proprio per questo display.
Devi inviare la cifra come int, moltiplicandola per 10 e poi aggiungere il comando per il punto decimale.
Con un if controlli se il numero è negativo e come primo carattere invii -
Dovresti modificare il codice di lettura della temperatura in modo che ti restituisca un intero moltiplicato per 10. Eviti cosi la conversione da float a int e risparmi memoria.
sinceramente non saprei come fare.... al momento sto usando la libreria DallasTemperature per leggere il sensore...
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
void setup(void)
{
// start serial port
Serial.begin(9600);
// Start up the library
sensors.begin(); // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement
}
void loop(void)
{
sensors.requestTemperatures();
Serial.print("Temperatura ");
Serial.print(sensors.getTempCByIndex(0));
Serial.println(" C");
}
void loop(void)
{
sensors.requestTemperatures();
Serial.print("Temperatura ");
Serial.print(sensors.getTempCByIndex(0));
Serial.println(" C");
int temperature = (int) (sensors.getTempCByIndex(0)*10);
i2cSendValue(temperature); //Send the four characters to the display
delay(1000);
}
void i2cSendValue(int temp)
{
Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
if (temp<0)
{
Wire.write(0x7B); // Seleziona la prima cifra
Wire.write(127); // invia il carattere -
}
Wire.write(temp / 1000); //Send the left most digit
temp %= 1000; //Now remove the left most digit from the number we want to display
Wire.write(temp / 100);
temp %= 100;
Wire.write(temp / 10);
temp %= 10;
Wire.write(temp); //Send the right most digit
Wire.write(0x77); // invia il punto decimale
Wire.write(4);
Wire.endTransmission(); //Stop I2C transmission
}
Funziona alla grande... l'unica cosa è che rimane fisso lo zero/gli zeri prima dei numeri della temperatura..come si vede in foto... si riesce a non farli accendere?
sotto lo zero non riesco a provare , ne con il ghiaccio, ne mettendo il sensore all'esterno anche se abito in Valle d'Aosta!
void i2cSendValue(int temp)
{
Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
if (temp<0)
{
Wire.write(0x7B); // Seleziona la prima cifra
Wire.write(127); // invia il carattere -
temp = temp * -1;
}
if (temp/1000>0)
{
Wire.write(temp / 1000); //Send the left most digit
}
else
{
Wire.write(0x79);
Wire.write(0x01);
}
temp %= 1000; //Now remove the left most digit from the number we want to display
if (temp/100>0)
{
Wire.write(temp / 100);
}
else
{
Wire.write(0x79);
Wire.write(0x02);
}
temp %= 100;
Wire.write(temp / 10);
temp %= 10;
Wire.write(temp); //Send the right most digit
Wire.write(0x77); // invia il punto decimale
Wire.write(4);
Wire.endTransmission(); //Stop I2C transmission
}
Prova...
Devo ancora ragionare per i numeri negativi. Ancora non mi convince.
Purtroppo non ho un display a 7 segmenti per fare le prove e sto scrivendo il codice a sentimento.
Ciao Paolo, scusa ma non ho avuto piu avuto il tempo di fare le prove...
posto lo sketch completo... per provare con il segno meno ho impostare im modo che superando i 25 gradi viene aggiunto il segno -
Funziona...solo che quando la temperatura ritorna al di sotto dei 25 gradi mantiene il segno meno... come si potrebbe fare? bisognerebbe resettare il display al cambio di segno?
ho provato...dato che per fare il segno meno ho usato Wire.write(0x7B); Wire.write(0b01000000);
ho pensato che magari inviando Wire.write(0x7B); Wire.write(0b00000000); non accendesse nessun led ma invece non funziona
/*
11-2-2012
Spark Fun Electronics
Nathan Seidle
This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
Serial7Segment is an open source seven segment display.
This is example code that shows how to send data over I2C to the display.
Note: This code expects the display to be listening at the default I2C address. If your display is not at 0x71, you can
do a software or hardware reset. See the Wiki for more info:
http://github.com/sparkfun/Serial7SegmentDisplay/wiki/Special-Commands
To get this code to work, attached an Serial7Segment to an Arduino Uno using the following pins:
A5 to SCL
A4 to SDA
VIN to PWR
GND to GND
*/
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define DISPLAY_ADDRESS1 0x71 //This is the default address of the OpenSegment with both solder jumpers open
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
void setup()
{
Wire.begin(); //Join the bus as master
sensors.begin();
Serial.begin(9600); //Start serial communication at 9600 for debug statements
//Send the reset command to the display - this forces the cursor to return to the beginning of the display
Wire.beginTransmission(DISPLAY_ADDRESS1);
Wire.write('v');
Wire.endTransmission();
}
void loop(void)
{
sensors.requestTemperatures();
Serial.print("Temperatura ");
Serial.print(sensors.getTempCByIndex(0));
Serial.println(" C");
int temperature = (int) (sensors.getTempCByIndex(0)*10);
i2cSendValue(temperature); //Send the four characters to the display
delay(1000);
}
void i2cSendValue(int temp)
{
Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
if (temp>250)
{
Wire.write(0x7B); // Seleziona la prima cifra
Wire.write(0b01000000); // invia il carattere -
}
if (temp/1000>0)
{
Wire.write(temp / 1000); //Send the left most digit
}
else
{
Wire.write(0x79);
Wire.write(0x01);
}
temp %= 1000; //Now remove the left most digit from the number we want to display
if (temp/100>0)
{
Wire.write(temp / 100);
}
else
{
Wire.write(0x79);
Wire.write(0x02);
}
temp %= 100;
Wire.write(temp / 10);
temp %= 10;
Wire.write(temp); //Send the right most digit
Wire.write(0x77); // invia il punto decimale
Wire.write(4);
Wire.endTransmission(); //Stop I2C transmission
}
ho provato così e il cambio di segno funziona... così non invia nulla sulla prima cifra Wire.write(0x7B); Wire.write(0b10000000);
però ho cambiato un po lo sketch...ed è da sistemare..in caso di 2 cifre o una cifra.
Nickb84:
posto lo sketch completo... per provare con il segno meno ho impostare im modo che superando i 25 gradi viene aggiunto il segno -
Funziona...solo che quando la temperatura ritorna al di sotto dei 25 gradi mantiene il segno meno... come si potrebbe fare? bisognerebbe resettare il display al cambio di segno?
Si, bisogna prevedere un sistema per includere o meno il segno in base al valore della temperatura.
Nickb84:
ho provato...dato che per fare il segno meno ho usato Wire.write(0x7B); Wire.write(0b01000000);
ho pensato che magari inviando Wire.write(0x7B); Wire.write(0b00000000); non accendesse nessun led ma invece non funziona
Certo che non funziona. Wire.write(0x7B); è un comando che dice al display di accendere i segmenti della prima cifra in base a quello che si trasmette subito dopo. La trasmissione immediatamente successiva è Wire.write(0b01000000); e il display accende il segmento numero 7.
Trovi le info qui --> Special Commands · sparkfun/Serial7SegmentDisplay Wiki · GitHub
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define DISPLAY_ADDRESS1 0x71 //This is the default address of the OpenSegment with both solder jumpers open
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
void setup()
{
Wire.begin();
sensors.begin();
Serial.begin(9600);
//Send the reset command to the display - this forces the cursor to return to the beginning of the display
Wire.beginTransmission(DISPLAY_ADDRESS1);
Wire.write('v');
Wire.endTransmission();
}
void loop(void)
{
sensors.requestTemperatures();
Serial.print("Temperatura ");
Serial.print(sensors.getTempCByIndex(0));
Serial.println(" C");
int temperature = (int) (sensors.getTempCByIndex(0)*10);
i2cSendValue(temperature); //Send the four characters to the display
delay(1000);
}
void i2cSendValue(int number)
{
Serial.print("Debug number: ");
Serial.println(number);
Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
Wire.write(0x76); // Clear display
Wire.write(0x79); // Set cursor
Wire.write(0x00); // at position 0
if (number<0) // Negative temperature
{
Wire.write(0x7B); // Digit 1 control
Wire.write(0b01000000); // Set segment X
number = number * -1;
}
Serial.print("1000 number: ");
Serial.println(number);
if (number>999)
{
Wire.write(number / 1000);
}
else
{
Wire.write(0x79);
Wire.write(0x01);
}
number %= 1000; //Now remove the left most digit from the number we want to display
Serial.print("100 number: ");
Serial.println(number);
if (number>99)
{
Wire.write(number / 100);
}
else
{
Wire.write(0x79);
Wire.write(0x02);
}
number %= 100;
Serial.print("10 number: ");
Serial.println(number);
if (number>9)
{
Wire.write(number / 10);
}
else
{
Wire.write(0x79);
Wire.write(0x03);
}
number %= 10;
Serial.print("1 number: ");
Serial.println(number);
Wire.write(number); //Send the right most digit
Wire.write(0x77); // Set Decimal
Wire.write(0b00000100);
Wire.endTransmission(); //Stop I2C transmission
}
Apri il serial monitor e dimmi che cosa ti esce. Ho messo dei serial print per fare il debug.
Si, appunto da quel link che ho capito come accendere il led 7... ;)...comunque con Wire.write(0x7B); Wire.write(0b10000000); ...Funziona! il passaggio dal segno - meno al +....spegne completamente la prima cifra... l'ultimo sketch che ho postato...è un po elementare però se imposto i vari intervalli dovrebbe funzionare credo... temp>0 ; temp>99 ; temp<0 ;temp>-99
secondo te non va bene?
Ho appena provato il tuo ultimo sketch... non gli piace il:
Nickb84:
Si, appunto da quel link che ho capito come accendere il led 7... ;)...comunque con Wire.write(0x7B); Wire.write(0b10000000); ...Funziona! il passaggio dal segno - meno al +....spegne completamente la prima cifra...
dal sito sembra che per accendere il meno debba accendere il 7° segmento quindi 0b01000000, ma se ti funziona con 0b10000000 allora va bene lo stesso.
Nickb84:
l'ultimo sketch che ho postato...è un po elementare però se imposto i vari intervalli dovrebbe funzionare credo... temp>0 ; temp>99 ; temp<0 ;temp>-99
secondo te non va bene?
No, gli intervalli da considerare sono
999
il numero ha 4 cifre quindi devi scriverle tutte nel display
99
numero a tre cifre. salti la prima casella e scrivi le altre tre.
9
numero a 2 cifre. salti la prima e la seconda e scrivi il numero nelle ultime due celle
infine c'è il numero ad una cifra.
lo scrivi nella quarta cella saltando le prime tre.
Se la temperatura è minore di 0, scrivi il meno e trasformi il numero in positivo controllando i casi precedenti.
Se misuri in °C non puoi misurare meno di -276 quindi non hai problemi con negativi a 4 cifre.
Per il problema col write(0) ho scritto nel post precedente.