Pages: [1] 2   Go Down
Author Topic: sensore temperatura ds18b20 e 7 segment display sparkfun  (Read 2726 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti ho acquistato da poco il nuovo 7segment display della Sparkfun.

Link:https://www.sparkfun.com/products/11442

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

Code:
/*
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

Code:
/*
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);
}


Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 573
Posts: 12626
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao Michele, non so se hai dato un'occhiata al link...questo è un nuovo display gia predisposto per la comunicazione I2C, Seriale, TTL,SPI
Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 573
Posts: 12626
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

no, pardon, ho riconociuto l'immagine e pensavo fosse il solito mux, alla luce di quanto dici le cose cambiano e purtroppo non so come aiutarti
Logged


Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7178
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: December 10, 2012, 09:19:36 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sinceramente non saprei come fare.... al momento sto usando la libreria DallasTemperature per leggere il sensore...

Code:
#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");
}
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7178
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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
}

Trovi i comandi per mandare il punto decimale qui --> https://github.com/sparkfun/Serial7SegmentDisplay/wiki/Special-Commands#wiki-decimal

Non ho idea se compila o meno. Non l'ho testato.
« Last Edit: December 11, 2012, 06:45:11 pm by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grandissimo Paolo! smiley

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!  smiley

Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

non sono riuscito ad inserire l'immagine e non so perché comunque viene visualizzato ad esempio 023.4 o 009.6
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7178
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

si, bisogna rivedere l'algoritmo.  smiley-roll-blue

Code:
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.

Puoi postare lo sketch completo?  smiley-wink
« Last Edit: December 12, 2012, 05:22:08 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao Paolo, scusa ma non ho avuto piu avuto il tempo di fare le prove... smiley-wink

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

Code:
/*
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
}




Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
void i2cSendValue(int temperature)
{
  Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
 
  if (temperature>250)
  {
  Wire.write(0x7B);
  Wire.write(0b01000000);
  Wire.write(0x79);
  Wire.write(0x01);
  Wire.write(temperature  / 100);
  temperature  %= 100;
  Wire.write(0x79);
  Wire.write(0x02);
  Wire.write(temperature  / 10);
  temperature  %= 10;
  Wire.write(0x79);   
  Wire.write(0x03);
  Wire.write(temperature );
  Wire.write(0x77);
  Wire.write(4);
  Wire.endTransmission();
  }
 else
 {
  Wire.write(0x7B); 
  Wire.write(0b10000000);
  Wire.write(0x79);
  Wire.write(0x01);
  Wire.write(temperature  / 100);
  temperature  %= 100;
  Wire.write(0x79);
  Wire.write(0x02);
  Wire.write(temperature  / 10);
  temperature  %= 10;
  Wire.write(0x79);
  Wire.write(0x03);
  Wire.write(temperature );
  Wire.write(0x77);
  Wire.write(4);
  Wire.endTransmission();
}
}


Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7178
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

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.  smiley-mr-green
Code:
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 è
Code:
Wire.write(0b01000000);
e il display accende il segmento numero 7.
Trovi le info qui --> https://github.com/sparkfun/Serial7SegmentDisplay/wiki/Special-Commands

Adesso provo a dare uno sguardo al codice.  smiley-wink
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7178
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Prova così.

Code:
#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.
« Last Edit: December 16, 2012, 05:25:09 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
Jr. Member
**
Karma: 0
Posts: 73
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si, appunto da quel link che ho capito come accendere il led 7... smiley-wink...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:

Wire.write(0x79);
Wire.write(0x00);
Logged

Pages: [1] 2   Go Up
Jump to: