arduino e lcd seriale...problemi grafici

salve a tutti ho da poco comprato il secondo arduino (dopo aver stupidamente bruciato il primo :-[) per un progetto molto semplice, creare un computerino di bordo per questo veicolo(cose del tipo velocità stato batteria ecc).
il grande problema che mi sono trovato di fronte utilizzando questo lcd sono appunto questi bug grafici che non riesco veramente a risolvere...
infatti quando vado a complicare un pò la grafica mi trovo con della grafica a caso(linee, quadrati, punti) che non ho messo io.

ho chiesto ad un pò di colleghi e alcuni mi hanno detto che potrebbe essere il boud rate, altri che il buffer del backpack dell'lcd va cancellato ogni tanto, altri ancora mi dicono che è il programma(spero che non sia così perchè questa è la quarta volta che ricomincio da capo il programma con grafica e "approcci" diversi).

voi cosa ne pensate...diciamo che ho qualcuno che mi alita sul collo per questo progetto e devo finirlo entro venerdì prossimo

se volete vi posso dare codice o altre informazioni

aspetto ansioso le risposte grazie in anticipo

ciao Ale92

Non sará semplice aiutarti perché per povare il tuo programma per capire il problema serve il display che dubito posseggono tanti.

Siccuramente come primo passo manda lo sketch e come hai collegato il display all'Arduino.

Dubito che sia il BaudRate perché se sbagliato non dovrebbe funzionare niente.

Ciao Uwe

Una causa del tuo problema può essere una routin che va a scrivere sul display con dati corrotti (sia che servano per indirizzare la grafica o per "plottare" un oggetto grafico in bitmap)
Fai per caso delle copie di parti della memoria di Arduino per simboli particolari o altro da visualizzare sul display?
Perchè se così fosse dovresti verificare di non avere overflow di stack o superamento dei limiti di array (o buffer che dir si voglia).
Non scordarti poi che gestire un'area di schermo di 2,5Kb con Arduino non è tanto semplice, soprattutto se hai bisogno di inviargli grosse parti di grafica (sempre in bitmap) tipo loghi o simile...

l'arduino bruciato che arduino è? lo sai che lo puoi comunque usare se hai bruciato l'FT232?
Praticamente devi pluggare l'arduino bruciato, se dall ide ti rileva la com allora l'F232 è salvo. Non dovrai far altro che seguire questo tutorial e riflashare il bootloader. A meno che non tu abbia rotto altri componenti o ci siano cortocircuiti sulla scheda.
http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
Io oggi ho recuperato 2 mega e un microcontrollore atmega168 su cui era caduta una lima .D

@calamaro...la scheda è l'arduino duemilanove, non so domani provo comunque ho dato 14 V sul pin 0 (quello analogico) e dopo fari scoppiettii ha smesso di funzionare...comunque mi pare che la usb la veda ancora, comunque giusto per averlo come riserva avevo ordinato un microprocessore nuovo(quello vecchio ha fatto una brutta fine...non l'ho presa benissimo quando ha smesso di funzionare XD)

io diciamo che uso per lo più la funzione quadrato che ho copiato dal datasheet(speriamo di averla copiata bene) non mi sono buttato sul disegno pixel per pixel ma domani sicuramente dalla disperazione proverò anche questo
scusa ma non capisco cosa intendi per "copie di parti della memoria di Arduino", vuoi dire i sottoprogrammi???

la quantità di dati che mando non è massiccia(secondo me)...dei delay possono aiutare?

il problema è che gli errori sono random e non ad un loop preciso...per favore aiutatemi non so più dove mettere le mani...

edit.
oggi ho provato anche a fare tutto a pixel ma ho avuto subito dei problemi

void Pixel(int x1, int y1)
{
  Serial.print(0x7C, BYTE);
  Serial.print(0x10, BYTE);
  Serial.print(x1, BYTE);
  Serial.print(y1, BYTE);
  Serial.print(0x01, BYTE);
}




 for(int i = 10; i < 90; i++)
  {
    Pixel(97,i);
  }

anche una cosa semplice come un for per fare una riga mi da parecchi problemi, cosa sbaglio?

Il fatto che tu "veda" una certa casualità negli errori non vuol dire necessariamente che siano "random".. è sufficiente che un contatore generi un valore che va erroneamente a sovrascrivere una variabile che poi inviii alla seriale per darti la medesima impressione... (una serie apparentemente casuale solo perchè lunga ed articolata).
Questo è un caso molto comune quando si hanno problemi di overflow nello stack (troppe funzioni nidificate).
I tuoi test li stai facendo con un programmino "bello magro" (nel senso: con le sole istruzioni di test) o sta provano il tutto con il software che dovrebbe servirti per il lavoro finale?
Nel caso il test sia "magro", hai verificato di non avere problemi nella comunicazione controllando i flag della seriale? (vedi post: Display LCD 20x4 seriale + arduino?) ink: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1274883645

il programma è solo quello con questa funzione, ora vado a vedere l'altro post anche se gli avevo gia dato un occhiata ma non ci avevo capito molto

l'istruzione Serial.available mi può essere utile?

Direi di no, perchè quella funzione ti dice solo se hai ricevuto dei caratteri...
Hai provato a verificare che non ci siano errori di trasmissione con quel codice che ho già postato?

Lo riposto anche qui:

/* serial test by kokiua */

// definizione funzioni utili
#define setBit(var, bitnum)   (var)|=(1<<(bitnum))
#define resBit(var, bitnum)   (var)&=~(1<<(bitnum))
#define testBit(var, bitnum)  (var)&(1<<(bitnum))

//definizione led di stato
#define PIN_err1    9  //acceso se Frame Error
#define PIN_err2   10  //acceso se Data OverRun
#define PIN_err3   11  //acceso se Parity Error
#define PIN_err4   12  //acceso se tutto ok

//variabili globali

int errore = false;

void setup()
{
  pinMode(PIN_err1, OUTPUT);
  pinMode(PIN_err2, OUTPUT);
  pinMode(PIN_err3, OUTPUT);
  pinMode(PIN_err4, OUTPUT);
  Serial.begin(9600);

  // da modificare se la seriale è usata per altri scopi
  Serial.println("Test protocollo della seriale");
}

void loop()
{
  if(testBit(UCSR0A, FE0)){ // indica errore "Frame Error"
       digitalWrite(PIN_err1, 1);
       errore = true;
  } else {
      digitalWrite(PIN_err1, 0);
  }
  
  if(testBit(UCSR0A, DOR0)){ // indica errore "Data OverRun"
       digitalWrite(PIN_err2, 1);
       errore = true;
  } else {
      digitalWrite(PIN_err2, 0);
  }
  
  if(testBit(UCSR0A, UPE0)){ // indica errore "Parity Error"
       digitalWrite(PIN_err3, 1);
       errore = true;
  } else {
      digitalWrite(PIN_err3, 0);
  }

  if(errore){
       digitalWrite(PIN_err4, 0);  //spegne led di tutto ok
  } else {
      digitalWrite(PIN_err4, 1);  //accende led di tutto ok
      errore = false;
  }
}

Ricorda che la stringa emessa in fase di setup la devi modificare per renderla compatibile con il dispositivo che hai collegato (in questo caso il Display) e vedi di non usare Serial.println() ma solo Serial.print()

Fammi sapere se hai un qualche errore!

sisi l'ho visto e stavo cercando di capire come funzionava...(non so se si è capito ma non sono molto pratico ;D) ...praticamente devo collegare lo schermo come al solito in più metto il led sui vari pin e vedo se si accendono...giusto?

edit

pinMode(1, OUTPUT);
  Serial.begin(115200);

uso questo al posto del println giusto?

Ok per i led che se tutto funziona dovrebbero restare spenti a parte il quarto (quello che dice che tutto è ok).
Al posto del println devi usare solo il print ovvero: Serial.print() perchè printnl aggiunge alla trasmissione il carattere di "a capo", utile solo se devi "stampare" una stringa su di una periferica di visualizzazione abbastanza intelligente da saper interpretare il codice di "a capo".

pinMode(1, OUTPUT); è solo l'impostazione del pin 1 come output che non c'entra nulla con la seriale ma solo con una uscita logica.
Serial.begin(115200); è la velocità di trasmissione (della quale devi essere certo che anche il display la utilizzi uguale!)

avendo un solo display sono andato a culo e l'ho attaccato direttamente al 12 per vedere se era tutto ok e il led si è acceso, quasi che speravo che non si accendeva almeno capivo cos'è che non funzionava...
ora che posso fare/provare???

sul mio programma l'aggiunta di qualche delay può aiutare secondo te???

Mi posti qui il sorgente da te usato per fare il test?

P.S. dove trovo il datasheet del display con le istruzioni precise della configurazione??

il datasheet è questo

dopo la tua domanda penso di non aver capito come fare il testo...io ho messo il tuo codice sull'arduino, invece cosa dovevo mettere?

il codice generale che uso è questo

//PIN
int schermo_pin = 1;
int carica_pin = 0;
int pin_fotoresistore = 1;
int pin_fotoresistore_uscita = 2;
//VARIABILI
int cont = 20;
int pulisci = 0;
int cont_fotoresistore = 25;
int controllo_batteria = 61;

void setup()
{
  ConfigureLCD();
  ClearScreen();
  Background();
}

void loop()
{
  if(cont == 85)
  {
    cont = 20;
  }
  Velocita(cont);
  Batteria(cont);
  cont = cont + 5;
  if(pulisci == 10)
  {
    ClearScreen();
    pulisci = 0;
    Background();
  }
  EraseBlock(21,11,49,89);
  EraseBlock(98,11,126,89);
  pulisci++;
  delay(400);
}

void ConfigureLCD()  //CONFIGURO LO SCHERMO
{
  pinMode(1, OUTPUT);
  Serial.begin(115200);
}

void ClearScreen()    //RIPULISCO LO SCHERMO
{
  Serial.print(0x7C, BYTE);
  Serial.print(0x00, BYTE);  // clear screen
}

void DrawBox(byte x1, byte y1, byte x2, byte y2)    //DISEGNO UN QUADRILATERO!!
{
  Serial.print(0x7C, BYTE);
  Serial.print(0x0F, BYTE);
  Serial.print(x1, BYTE);
  Serial.print(y1, BYTE);
  Serial.print(x2, BYTE);
  Serial.print(y2, BYTE);  
}

void EraseBlock(int x1, int y1, int x2, int y2)    //CANCELLO UN'AREA DELIMITATA DAI VERTICI CON COORDINATE X1, Y1 E X2, Y2
{
  Serial.print(0x7C, BYTE);
  Serial.print(0x05, BYTE);
  Serial.print(x1, BYTE);
  Serial.print(y1, BYTE);
  Serial.print(x2, BYTE);
  Serial.print(y2, BYTE);
}

void SetXY(int x, int y)      //POSIZIONO IL CURSORE SUL PIXEL DETERMINATO DALLE COORDINATE X E Y
{
  Serial.print(0x7C, BYTE);
  Serial.print(0x18, BYTE);
  Serial.print(x, BYTE);
  Serial.print(0x7C, BYTE);
  Serial.print(0x19, BYTE);
  Serial.print(y, BYTE);
}
void Background()
{
    SetXY(25,120);
    Serial.print("CLASSE VIRTUALE 2010");
    SetXY(20,100);
    Serial.print("SPEED");
    SetXY(97,100);
    Serial.print("BATTERY");
    
    //SPEED
    DrawBox(20,10,50,90);
    SetXY(13,10);
    Serial.print("0");
    SetXY(13,30);
    Serial.print("5");
    SetXY(7,50);
    Serial.print("10");
    SetXY(7,70);
    Serial.print("15");
    SetXY(7,90);
    Serial.print("20");
    
    //BATTERY
    DrawBox(97,10,127,90);
    SetXY(78,90);
    Serial.print("100");
    SetXY(84,70);
    Serial.print("75");
    SetXY(84,50);
    Serial.print("50");
    SetXY(84,30);
    Serial.print("25");
    SetXY(90,10);
    Serial.print("0");
}

void ReverseMode()        //INVERTO I COLORI DELLO SCHERMO
{
  Serial.print(0x7C, BYTE);
  Serial.print(0x12, BYTE);
}

//void Fotoresistore()  //FARI ACCESI/SPENTI IN BASE ALLA LUCE
//{
//  int valore1 = 0;
//  int valore2 = 920;
//  valore1 = analogRead(pin_fotoresistore);
//  if(valore1 >= valore2)
//  {
//    digitalWrite(pin_fotoresistore_uscita, HIGH); 
//  }
//  else
//  {
//    digitalWrite(pin_fotoresistore_uscita, LOW); 
//  }
//}

void Velocita(int riga)
{
  DrawBox(21, riga, 49, riga);
}

void Batteria(int riga)
{
  DrawBox(98, riga, 126, riga);
}

quando arrivo a casa posto un paio di foto...ora con il firewall di lavoro non riesco nemmeno a mettere un immagine su internet

Allora...
Questo è il "vero" datasheet del controller del display: http://www.sparkfun.com/datasheets/LCD/Monochrome/Datasheet-T6963C.pdf con il quale hai la possibilità di sfruttare al massimo il dispositivo..

Per quanto riguarda il collegamento, visto che usi la velocità di 115200, che tipo di connessione fisica hai usato?
ovvero:
E' molto lunga la connessione? (più corta è meglio è)
E' una normale piattina o fili singoli sfusi? (meglio usare cavi schermati)
Se è schermato, hai attaccato tutte e due i capi della calza (la schermatura) o uno solo? (sempre e solo uno solo!)
Hai provato con una velocità di connessione inferiore?

Per passare da 115200 ad altra velocità dovrai modificare così:

void ConfigureLCD()  //CONFIGURO LO SCHERMO
{
  pinMode(1, OUTPUT);
  Serial.begin(115200);
  Serial.print(0x07, BYTE); //nuova velocità seriale al display
  Serial.print("2"); //1=4800,2=9600,3=19200,4=38400,5=57600,6=115200
  Serial.begin(9600);
}

Dovresti provare con una velocità bassa per poi aumentare sino a quando non hai problemi.

Fammi sapere se ora è più stabile :wink:

domani provo tutto perchè la roba ce l'ho tutta in azienda

comunque queste sono le foto con gli errori
foto1

foto2

nella prima c'è quel quadrato lì che non centra niente
nella seconda anche se è sfocata si vede che manca gran parte della grafica

Fai le prove a velocità inferiore e soprattutto verifica che il collegamento sia il più corto possibile e schermato a dovere..

I "difetti" che mi hai mostrato possono essere benissimo degli errori di trasmissione. E' sufficiente che i dati inviati possano essere mal interpretati dal display con cancellazione di parti o plotting di grafica non controllati.

Dopo che avrai fatto tutte le prove, se la cosa si ripete, puoi provare anche questo: potrebbe essere un problema di connessione tra il modulo seriale e il display. Nel qual caso ti consiglio di provare a rimuovere il modulo e ricollegarlo (sempre che ci sia un normale connettore...).

La cosa migliore per verificare il display dovrebbe essere quella di collegarne un'altro per escludere il problema del display.

ancora non ho provato ma io ho 2 display uguali e li ho provati su entrambi ma niente

il cavo è lungo un metro + o - ed è tutto schermato tranne la fine dei cavi e l'inizio dei cavi

il codice che cambia il boud rate devo metterlo sempre giusto(cioè non che se lo cambio una volta cambia per sempre)???

Ti sembrerà strano ma ho come l'impressione di sostenere la stessa discussione in due post diversi: il tuo e quell'altro dove avevo già postato l'esempio del test...
Come ho scritto li, mi è venuto il sospetto che il mio prog per il test della seriale possa non funzionare a causa della libreria di Arduino che magari resetta i flag di errore... (e quindi non si riesce a fare il test)
Se trovo 5 minuti provo a controllare la libreria interna e vedo se è così, poi vi faccio sapere...

(certo che se una buona anima che ha "creato" l'Arduino si mettesse la mano sul cuore ed intervenisse su questo problema.. )