problema i2c

Buongiorno a tutti,
ho realizzatoun misuratore di consumi senza usare la libreria emolib, funziona correttamente ma avevo bisogno di aggiungere una sd per memorizzare i valori e un oprologio. Se aggiungo le librerie wire.h o sd arduino si blocca .Allego il mio programma:

//#include <Wire.h>
//#include <SD.h>
#include "U8glib.h"

U8GLIB_ST7920_128X64 u8g(3, 2, 17, U8G_PIN_NONE);  
int y,x1,y1;
int ch1[300],ch3[300],pw1[25],pw2[25];
int c=14;//fattore moltiplicazione valore rilevato
float e=0.18; // prezzo al kw
long poggi1=0,poggi2=0;
int xa=0,xb=0,h=0;
long p1=0,p2=0,ph1=0,ph2=0,t1;
byte  s=0;
float e1,e2;
String e3;
void setup(void) {
   Serial.begin(9600);
   u8g.setRot90();
   t1=millis();
  }
  
  void draw(void){
  u8g.setFont(u8g_font_6x10);
  //u8g.setFont(u8g_font_osb21);
     u8g.setPrintPos(1,7);
      u8g.print ("Prese");
       
       u8g.setPrintPos(1,73);
      u8g.print ("Luce");
      
      u8g.setPrintPos(1,42);
      u8g.print ("Oggi");
      
      u8g.setPrintPos(1,106);
      u8g.print ("Oggi");
      
      u8g.setFont(u8g_font_fub14);
     u8g.setPrintPos(0,30);
    //u8g.setFont(u8g_font_6x10);
  u8g.print((p1*c));
  //u8g.print(1999);
  u8g.print ("W");
   u8g.setPrintPos(0,94);
   //u8g.print(2999);
    
   u8g.print (p2*c);
   u8g.print ("W");
   u8g.setFont(u8g_font_fub11);
   
     u8g.setPrintPos(0,60);
    u8g.print((poggi1*c*1.00)/1000);
  //u8g.print (h);
   u8g.print (e3);
   u8g.setPrintPos(0,125);
    u8g.print((poggi2*c*1.00)/1000);
  u8g.print (e3);
 

  u8g.drawHLine(0,63,64);
  u8g.drawHLine(0,64,64);
  u8g.drawHLine(0,32,64);
  u8g.drawHLine(0,96,64);
  //u8g.drawHLine(0,64,64);
  //u8g.drawVLine(0, 0, 64);
}
  
  
  
  
  
  
  
  
  void loop(void) {
    p1=0;
    p2=0;
    //t1=millis();
   for( xa = 0; xa < 16; xa++ ){ //xa per avere 2 secondi alla fine del loop
    int valore1=0,valore2=0;
    int ch2=analogRead(A1);
     //t1=micros();
     for( int x = 0; x < 299; x++ ){
       ch1
=analogRead(A0);
      
         delayMicroseconds(87);// 3 periodi completi per 60ms
         
    }
 
    //t1=t1-micros();
    
  for( int x = 0; x < 299; x++ ){
       ch3
=analogRead(A3);
        delayMicroseconds(87);// 3 periodi completi per 60ms
         
    }
    
    
     for( int x = 0; x < 299; x++ ){
    valore1=abs(ch1
-ch2);
   valore2=abs(ch3
-ch2);
      p1=p1+valore1;
       p2=p2+valore2;
    }
    }
    p1=p1/(299*xa);
    p2=p2/(299*xa);
  
                delay(61); // completa i 2 secondi
     
     ph1=ph1+p1; // somma i valori medi ogni 2 secondi
     ph2=ph2+p2;
     xb++;
  // if (millis()-t1 > 3600000){  //dopo 1 ora calcola il consumo w/h
     if (millis()-t1 > 3600){  //dopo 1 ora calcola il consumo w/h
     
     h++;
     pw1[h]=ph1/xb; //salva il consumo di 1 ora 
     pw2[h]=ph2/xb;
     
     poggi1=poggi1+pw1[h];
     poggi2=poggi2+pw2[h];
     t1=millis();
     if (h==24) { 
       h=0;
       poggi1=0;
       poggi2=0;
      } 
       Serial.println(h);
         Serial.println(poggi2);
     }
     
     if (s==0){
     e1=(poggi1*c*1.00)/1000;
     e2=(poggi2*c*1.00)/1000;
     e3="Kh";
     s=1;
     }
     else {
        e1=(poggi1*c*e)/1000;
     e2=((poggi2*c)/1000)*e;
     e3="e";
     s=0;
       }
     u8g.firstPage();  
   do {
   draw();
  } while( u8g.nextPage() );  
     //delay(5000);
     }

Grazie
Gino

Il codice lo devi mettere nei tag code (pulsante #) Se guardi nel regolamento, sezione 7 spiega come fare.

Mi viene il dubbio che tutte quelle librerie insieme possano occupare troppa memoria su Arduino Uno.

Credo di aver capito come scrivere il topic, ora dovrebbe essere corretto. Per quanto riguarda la librerie ho provato a fare un orologio con la libreria wire per il mio rtc e u8glib per il display e funziona, pensi che il mio array occupi troppa memoria?
Qualcuno mi sa spiegare i limiti di memoria utilizzando gli array?
Grazie
Gino

La SRAM di Arduino Uno è 2048 byte (2K) ogni elemento dell'array dipende dalla dichiarazione davanti al suo nome.

int ch1[300]

Nel tuo caso int, perciò 2 byte * 300 elementi => 600 byte Poi hai anche altre variabili. Un long occupa 4 byte, ogni int 2 byte, float 4 byte. Poi hai un oggetto String, quella purtroppo non definisce uno spazio fisso iniziale ma durante l'esecuzione (run-time) occupa memoria. Se concateni String alloca rialloca e rilascia SRAM. A volte può risultare memoria deframmentata e non più utilizzabile.

Potresti usare la libreria/funzione freeRam() da mettere nel setup() per sapere quanta SRAM libera in partenza.

int freeRam () 
{ extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Dove serve: Serial.println(freeRam());

Grazie, questa sera provo a verificare la ram dispobibile. Gino :) :) :) :) :)

Complimenti !!!!! Si hai ragione, togliendo un array e includendo una libreria alla volta ho scoperto che wire.h occupa circa 200 byte mentre sd circa 700 byte.E' normale? Il compliatore non dovrebbe dare un warning della memoria occupata? C' è una lista di quanto occupa ogni libreria? Ultima domanda, di norma quanti byte bisogna lasciare liberi per un corretto funzionemento, chiedo questo perche includendo la libreria sd che occupa quasi tutta la ram dell'atmel i valori della string variano casualmente. Comunque grazie, utilizzerò le tue righe di codice per controllare lo spazio .

Grazie Gino

Per chiarirti le idee, consiglio la lettura di QUESTO interessante artcolo di Leo e magari anche di QUESTO ;)

Guglielmo

Grazie, domani leggo l’articolo con calma. Molto interessante, notte a tutti.
Gino

La SD usa l’interfaccia SPI non la I2C.

#include <SPI.h>
#include <SD.h>

Grazie della precisazione, il problema era nato con la libreria wire(i2c) poi avevo notato il problema anche con sd. Grazie comunque. Gino