Go Down

Topic: Sauvegarde sur SD + Problème FM (Read 2766 times) previous topic - next topic

nathan30

Bonjour, j'ai bidouillé le code suivant :

Code: [Select]
/******************* Librairie ***********/

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SD.h>
#include <SPI.h>
#include <avr/sleep.h>
#include <OneWire.h>
#include <VirtualWire.h>

/****************** Fin librairie ********/

/*************** Définition des pins ****/

#define SD_CS    4  // Pin pour la carte SD
#define TFT_CS  10  // Pin pour l'affichage TFT
#define TFT_DC   8  // Pin pour les commandes TFT
#define TFT_RST  -1  //Pin du reset (Ou connecté au +5V)
#define trigPin A3
#define echoPin 5

/********** Fin définition des pins ****/

/******** Définition des boutons + couleurs + variables *****/

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

#define BUTTON_NONE 0
#define BUTTON_DOWN 1
#define BUTTON_RIGHT 2
#define BUTTON_SELECT 3
#define BUTTON_UP 4
#define BUTTON_LEFT 5
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
int count = 0 ;
int thisByte = 33;
int DS18S20_Pin = 7;
OneWire ds(DS18S20_Pin);
File Temp;

/******************* Fin Définition des boutons + couleurs + variables **************************/

/************************* Capture de température INTERNE ***********************************/
float getTemp(){

 byte data[12];
 byte addr[8];

 if ( !ds.search(addr)) {
   //no more sensors on chain, reset search
   ds.reset_search();
   return -1000;
 }

 if ( OneWire::crc8( addr, 7) != addr[7]) {
   Serial.println("CRC is not valid!");
   return -1000;
 }

 if ( addr[0] != 0x10 && addr[0] != 0x28) {
   Serial.print("Device is not recognized");
   return -1000;
 }

 ds.reset();
 ds.select(addr);
 ds.write(0x44,1); // start conversion, with parasite power on at the end

 byte present = ds.reset();
 ds.select(addr);    
 ds.write(0xBE); // Read Scratchpad


 for (int i = 0; i < 9; i++) { // we need 9 bytes
   data[i] = ds.read();
 }

 ds.reset_search();

 byte MSB = data[1];
 byte LSB = data[0];

 float tempRead = ((MSB << 8) | LSB); //using two's compliment
 float TemperatureSum = tempRead / 16;
 return TemperatureSum;
}



/************************ Fin de capture de température INTERNE **********************************/

/************************                  Setup                *********************************/
void setup(void)
{
 Serial.begin(9600);
 vw_set_ptt_inverted(true); // Required for DR3100
 vw_setup(2000); // Bits per sec

 /***************                Sauvegarde sur SD           ************************************/
 // Open serial communications and wait for port to open:
 Serial.begin(9600);

 Serial.print("Initializing SD card...");
 // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
 // Note that even if it's not used as the CS pin, the hardware SS pin
 // (10 on most Arduino boards, 53 on the Mega) must be left as an output
 // or the SD library functions will not work.
 pinMode(10, OUTPUT);

 if (!SD.begin(4)) {
   Serial.println("initialization failed!");
   return;
 }
 Serial.println("initialization done.");

 // open the file. note that only one file can be open at a time,
 // so you have to close this one before opening another.
 Temp = SD.open("test.txt", FILE_WRITE);

 // if the file opened okay, write to it:
 if (Temp) {
   Serial.print("Writing to test.txt...");
   Temp.println("Temperature interne :");
   Temp.print(getTemp);
   Temp.flush();
   Temp.close();
   Serial.println("done.");
 }
 else {
   // if the file didn't open, print an error:
   Serial.println("error opening test.txt");
 }

 // re-open the file for reading:
 Temp = SD.open("test.txt");
 if (Temp) {
   Serial.println("test.txt:");

   // read from the file until there's nothing else in it:
   while (Temp.available()) {
     Serial.write(Temp.read());
   }
   // close the file:
   Temp.close();
 }
 else {
   // if the file didn't open, print an error:
   Serial.println("error opening test.txt");
 }


 /***************              Fin sauvegarde sur SD           ************************************/

 tft.initR(INITR_REDTAB);   // initialize a ST7735R chip, red tab
 // If your TFT's plastic wrap has a Green Tab, use the following:
 //tft.initR(INITR_GREENTAB); // initialize a ST7735R chip, green tab

 Serial.println("OK!");
 tft.fillScreen(0x0000);
 tft.setRotation(1);
}

/************************                Fin Setup             *********************************/

/************************                Partie écran          *********************************/


uint8_t readButton(void)
{
 float a = analogRead(3);

 a *= 5.0;
 a /= 1024.0;

 Serial.print("Button read analog = ");
 Serial.println(a);
 if (a < 0.2) return BUTTON_DOWN;
 if (a < 1.0) return BUTTON_RIGHT;
 if (a < 1.5) return BUTTON_SELECT;
 if (a < 2.0) return BUTTON_UP;
 if (a < 3.2) return BUTTON_LEFT;
 else return BUTTON_NONE;
}

uint8_t buttonhistory = 0;


void loop()
{
 count++;

 /****************** Envoie par FM ****************/

 digitalWrite(13, true); // Flash a light to show transmitting
 vw_send((uint8_t *) &getTemp, sizeof(int));
 vw_wait_tx(); // Wait until the whole message is gone
 digitalWrite(13, false);
 delay(200);
 /**************** Fin envoie par FM *************/


 uint8_t b = readButton();
 tft.setTextSize(2);

 if (buttonhistory == 0)
 {
   tft.setTextColor(ST7735_GREEN);
   tft.setCursor(0, 0);
   tft.print ("  CHALET\n  ISOLE");
   tft.setTextColor(ST7735_RED);
   tft.setCursor(0, 60);
   tft.print (" Bonjour,\n Appuyez \n pour \n demarrer");
   while(b != BUTTON_SELECT)  b = readButton();
   buttonhistory |= 0;

   delay (1000);

   tft.fillScreen(BLACK);
   tft.setTextColor(ST7735_RED);
   tft.setCursor(0, 0);
   tft.print ("T interne :-> \n");
   tft.print ("T externe : \n");
   tft.print ("Niv d'eau :  \n");
   tft.print ("Veille : <- \n");
   buttonhistory |= 1;
 }

 if (b == BUTTON_DOWN)
 {
   tft.fillScreen(BLACK);
   tft.setTextColor(ST7735_RED);
   tft.setCursor(0, 10);
   tft.print("T Int =\n ");
   tft.print (getTemp());
   tft.print ("\xf7 C");
   buttonhistory |= 2;
 }

 if (b == BUTTON_LEFT)
 {
   tft.fillScreen(BLACK);
   tft.setTextColor(ST7735_YELLOW);
   tft.setCursor(0, 60);
   tft.print("T Ext =\n");
   tft.print (getTemp());
   tft.print ("\xf7 C");
   buttonhistory |= 3;
 }
 if (b == BUTTON_RIGHT)
 {
   tft.fillScreen(BLACK);
   tft.setTextColor(ST7735_GREEN);
   tft.setCursor(0, 110);
   tft.print("Niv Eau = ");
   tft.print(count);
   tft.print ("%");
   buttonhistory |= 4;
 }

 /************************             Mode veille (à optimiser..) *****************************/



 if (b == BUTTON_UP)
 {
   tft.setTextColor(ST7735_WHITE);
   tft.fillScreen(BLACK);
   tft.setCursor(0, 10);
   tft.print("Mode veille"); // Message de mis en sommeil
   delay (2000);
   tft.fillScreen(BLACK);
   delay(100);      
   set_sleep_mode(SLEEP_MODE_IDLE); //Définition du mode sommeil
   sleep_mode();  // Activation du mode veille
   count = 0;
 }    


 if (b == BUTTON_SELECT)  
 {
   sleep_mode();
   sleep_disable ();
   tft.print ("Sortie");  
   tft.fillScreen(BLACK);
   tft.setTextColor(ST7735_RED);
   tft.setCursor(0, 0);
   tft.print ("T interne : D \n");
   tft.print ("T externe : B\n");
   tft.print ("Niv d'eau : H\n");
   tft.print ("Veille :  G\n");
   buttonhistory |= 5;
 }
 /************************                 fin Mode veille         *****************************/


 /************************               Fin partie écran          *****************************/
}


Je dis bidouiller car c'est pas super bien organiser je l'avoue...

Bref, le soucis, quand je vérifie si il y a des erreurs, j'ai comme message :
Code: [Select]
Ecran:131: error: call of overloaded 'print(float (&)())' is ambiguous

Le problème vient donc d'ici :
Code: [Select]
Temp.print(getTemp);

Je ne comprends pas.. Quand je met le code a part pour la sauvegarde sur SD, avec une variable getTemp en float, je n'ai pas ce message d'erreur.. Une idée ?

SUITE AU POST SUIVANT CAR PLUS DE PLACE..

nathan30

Ensuite, pour la partie FM
Le recepteur a comme code (Merci Skywodd) :

Code: [Select]
#include <VirtualWire.h>
float getTemp;

void setup()
{
   Serial.begin(9600); // Debugging only
 
   // Initialise the IO and ISR
   vw_set_ptt_inverted(true); // Required for DR3100
   vw_setup(2000); // Bits per sec

   vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
   uint8_t buf[VW_MAX_MESSAGE_LEN];
   uint8_t buflen = sizeof(float);

   if (vw_get_message((uint8_t *) &getTemp, &buflen)) // Non-blocking
   {
int i;

       digitalWrite(13, true); // Flash a light to show received good message
// Message with a good checksum received, dump it.

for (i = 0; i < buflen; i++)
{
   Serial.print(float(getTemp));
   Serial.print(" ");
}
Serial.println("");
       digitalWrite(13, false);
   }
}


Et donc quand je branche mon arduino emetrice, elle envoie bien un signal, et la variable getTemp en plus normalement. Mais côté recepteur, je recois seulement "0.00".. Pourquoi ?..


Merci d'avance de votre aide..

nathan30


Viproz

Tu déclare getTemp comme une fonction puis tu l'utilise comme une variable, si c'est bien une fonction remplace par getTemp()

nathan30

Oh, merci beaucoup ! L'IDE ne me met pas d'erreurs, j'attends Lundi de pouvoir tester !! :D


nathan30

Et, pour la partie FM ? ..

Si je met getTemp() j'ai l'erreur suivante :
Code: [Select]
202: error: lvalue required as unary '&' operand..

Viproz

Pour cette partie, le nom de la variable n'est pas très bien choisi je trouve mais soit tu n'as pas donné le code complet soit il te manque quelque chose

Code: [Select]
uint8_t buf[VW_MAX_MESSAGE_LEN];

As tu défini VW_MAX_MESSAGE_LEN plus haut ?

Sinon je trouve le cast assez bizarre, un float est de 32 bits et le le met dans du 8 bits ?

Ha en fait tu as changé que quelques parties du code en enlevant des choses essentielles. Enfin, j'ai plus les idées très claires mais le prblème vient de la ligne
Code: [Select]
if (vw_get_message((uint8_t *) &getTemp, &buflen)) // Non-blocking

nathan30


Pour cette partie, le nom de la variable n'est pas très bien choisi je trouve mais soit tu n'as pas donné le code complet soit il te manque quelque chose


Quelle partie ?.. Le code est complet là..



Code: [Select]
uint8_t buf[VW_MAX_MESSAGE_LEN];

As tu défini VW_MAX_MESSAGE_LEN plus haut ?


Comment le faire ? J'ai pris les code du tuto de skywodd. Quand je met le programme en dehors du programme principal, cela fonctionne c'est pour ca que je me pose de questions..


Sinon je trouve le cast assez bizarre, un float est de 32 bits et le le met dans du 8 bits ?

Ha en fait tu as changé que quelques parties du code en enlevant des choses essentielles. Enfin, j'ai plus les idées très claires mais le prblème vient de la ligne
Code: [Select]
if (vw_get_message((uint8_t *) &getTemp, &buflen)) // Non-blocking


Je devrais passer sur un int sinon ?

Oui c'est bien cette ligne, et je comprends pas pourquoi..

nathan30


skywodd

Bonjour,

Un mot : aie.
Tes deux codes mériteraient d'être repris proprement de zéro.
Entre les noms de variables ambigües (même le compilateur te le dit !), l'ouverture du fichier systématique dans le code n°1, ...
C'est pas très jolie tout ça ;)

Erreur #1 :
Code: [Select]
Temp.print(getTemp);
Ici getTemp() est une fonction sans argument, il faut donc des () :
Code: [Select]
Temp.print(getTemp());

Erreur #2 :
Code: [Select]
vw_send((uint8_t *) &getTemp, sizeof(int));
getTemp() est toujours une fonction et elle retourne un float (pas un int !).

Nb: VirtualWire a besoin d'une variable pour fonctionner.
Pas d'un pointeur sur une valeur de retour (syntaxiquement c'est correct mais le fonctionnement de cette "chose" n'est pas franchement définissable).
Code: [Select]
float tmp = getTemp();
vw_send((uint8_t *) &tmp, sizeof(float));


Après même avec ça je suis pas sûr que le reste va suivre ...
Dans le code de réception tu as conservé des morceaux de mon ancien code qui sont inutile (la variable buf par exemple, la boucle d'affichage par octet, ...).
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

nathan30

Merci Skywodd,

Mais j'ai du me débrouiller tout seul cette fois çi. J'ai juste pris un autre code pour le température (Qui se place dans la boucle loop), donc voilà, tout marche :)

Le code serait à optimiser je sais, mais je n'ai pas le temps (oral vendredi)

Go Up