Arduino Driver libraries (Baustelle): Displays, SD, I2C, UART,...

Atmel, PIC, VEX, Fischertechnik

Moderator: Moderatoren

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Arduino-Hardware Driver libraries: Displays (Baustelle)

Beitragvon HaWe » 17. Jan 2015 10:25

(Platzhalter)

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Arduino-Hardware Driver libraries: Displays (Baustelle)

Beitragvon HaWe » 24. Jan 2015 19:33

Plazhalter

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C

Beitragvon HaWe » 25. Feb 2015 09:30

SD Karten-Module:

SD_57.JPG

Treiber-Library:
Arduino-SD-lib <SD.h> (standardmäßig in Sketch enthalten)
http://arduino.cc/en/pmwiki.php?n=Reference/SD
Schnittstelle: SPI <SPI.h>
Update, neu getestet: funktioniert grundsätzlich sowohl mit AVR Arduinos als auch mit Due.

Bezugsquelle: z.B. über Ebay: http://www.ebay.de/sch/i.html?_odkw=SD+ ... =&_sacat=0

Besonderheiten:
es werden von der Arduino-Sketch-API leider absolut keine stdio.h-File-Funktionen unterstützt, z.B. gibt es in der SD-Klasse kein fprintf und kein fscanf, sondern nur z.B. Funktionen wie (myFile).print und (myFile).println zum Schreiben,
und nur (myFile).read zum Byte-weise Lesen, was die Sache sehr umständlich macht
(z.B. noch nicht einmal ein (myFile).readln gibt es, was am ehesten wenigstens einem fgets() gleichkäme !)

Dann muss man wissen, dass die schlauen Arduino-Entwickler für float viele Formatierungs-Möglichkeiten einfach weggelassen haben.
Wenn man aber diese Libs installiert, geht es doch (Ordner ins entsprechende Systemverzeichnis kopieren, z.B:
xcopy *.* C:\Programme\Arduino\hardware\tools\avr\avr\lib /E /Y)
libc_all.zip
lib.c float-Patch
(1 MiB) 138-mal heruntergeladen


Zum Schreiben und Lesen von Strings und formatierter Variablen in SD-Files habe ich daher eigene Funktionen
fprintf_() , fgets_() und fscanf_()
geschrieben, die praktisch genau so arbeiten wie die Originale in ANSI C, und ein paar weitere, die die Handhabung vereinfachen.

Header:

Code: Alles auswählen

long     fprintf_( File * stream, const char fmtstr[], ... );       // see ANSI C: fprintf()
long     fscanf_ ( File * stream, const char fmtstr[], ... ) ;      // see ANSI C: fscanf()
char   * fgets_  ( char * str, int32_t num, File * stream );        // see ANSI C: fgets()
File     fopen_  ( char * filename, const char * mode );            // see ANSI C: fopen()
int16_t  fclose_ ( File   file_);                                   // see ANSI C: fclose()   
int16_t  remove_ ( char * filename);                                // see ANSI C: remove()
 

char  * ftoa(char * str, double f, int16_t precision );             // converts float to string by precision (digits)

char  * strinsert( char * source, char * sub, int pos );            // insert a substr into a string at pos
char  * strdelnpos(char * source, int16_t  pos, int16_t  sublen);   // delete a substr in string at pos
char  * strpatch ( char * source, char * sub, int pos );            // patch string by substr at pos
char  * substr  (  char * source, char * sub, int pos, int len );   // get substring of source string at pos by length
int16_t strchpos(  char * str, char ch );                           // find 1st occurence of char ch in string str
int16_t strstrpos( char * haystack,  char * needle)                 // find 1st occurance of substr in str
char  * stradd(char * s, int n, ...)  // "adds strings" s=sumstring , n=number_in_list, ... = var string list


kompletter Code siehe ganz unten!

Hier ein paar Erklärungen und der Sourcecode:

int32_t fprintf_ ( File * stream, const char fmtstr[], ... )
arbeitet wie das stdio.h C-Original fprintf(): Es schreibt einen string in ein file, dabei werden die Variablen/Argumente entsprechend dem formatstring als strings formatiert (gleiche Funktionsweise wie auch bei printf oder sprintf)

char * fgets_ ( char * str, int32_t num, File * stream )
Liest entsprechend der Original C-stdio.h Funktion einen string aus einem File, bis eine String-Terminierung oder ein Zeilenumbruch oder eof() oder die max Länge des übergebenen Puffers erreicht ist (je nachdem, was früher eintritt).
Im Falle dass "mein" fgets_() keine lesbaren Daten findet, kann optional auch ein Leerstring ("") zurückgegeben werden anstelle eines Nullpointers NULL wie bei Original fgets() - natürlich kann man das individuell anpassen.


int32_t fscanf_ ( File * stream, const char fmtstr[], ... );
liest einen String aus einem File und re-formatiert alle darin enthaltenen Variablen entsprechend dem Formatstring
(also %d zu int und %f zu float).
Eingebundene libs funktionieren u.U. nur auf ARM Plattform, nicht auf AVR (Einschränkung der Arduino-IDE !)
Achtung: nach C-Standard müssen alle ints 32-Bit sein (int32_t),
und Dezimalpunkte im float-Formatierer sind nicht erlaubt ("%f" und "%08f" erlaubt, "%8.2f" aber NICHT!);
teilw. Probleme mit double, float funktioniert aber.
Die nötige Compiler-Unterstützung liefert Arduino leider nur für ARM cpus.
Unterschied zum ANSI-C-fscanf():
fscanf_() liest intern immer einen Teilstring ("Block") aus dem stream mindestens bis zum nächsten Zeilenvorschub '\n',
aus diesem Teilstring werden dann die entsprechenden Variablen laut Formatstring herausgefiltert und zugewiesen.
wichtig: es dürfen mehrere Variablen in dem gelesenen String stehen,
als Begrenzer zwischen den Variablen dienen Leerzeichen oder spezielle angegebene Zeichen.
Aber es muss aber im Original-File immer am Schuss des zu lesenden Teilstring-Blocks mindestens ein '\n' stehen.
Dieser letzte Zeilenvorschub ist automatisch der Schluss-Begrenzer und muss beim Lesen mit fscanf() dann nicht mehr mit angegeben werden (s.o.).


Aufruf z.B.:

Code: Alles auswählen

File myFile;
char sdata[128];



fprintf_(&myFile, "%s\n%d\n%d\n%f\n%f\n", "EinTeststring", 1, 2, PI, 4.567890);
// schreibt die 5 Variablen (1x string, 2x int, 2x float), getrennt durch Zeilenumbrüche, in ein File.

fprintf_(&myFile, "%s %d %d %f %f\n", "EinTeststring", 1, 2, PI, 4.567890);
// dto, aber getrennt durch Leerzeichen, Zeilenvorschub am Ende des "Blocks".

fprintf_(&myFile, "%s;%d;%d;%f;%f;\n", "EinTeststring", 1, 2, PI, 4.567890);
// dto, aber getrennt durch Semikolons, am Ende des "Blocks" wieder ein Zeilenvorschub.





fgets_ ( sdata, 20, &myFile );
// liest und kopiert aus der Datei einen Teilstring in den String-Buffer "sdata",
// der dann anschließend als string oder umgewandelt zu int oder float weiterverwendet werden kann.





int32_t  m, n, cnt;
float    x, y;

fscanf_ ( myFile,  "%d %d %f %f ",  &m, &n, &x, &y );
// oder
cnt = fscanf_ ( myFile,  "%d %d %f %f \n",  &m, &n, &x, &y );
// liest einen Teilstring ("Block") aus einem File,
// re-formatiert die 4 darin enthaltenen Variablen entsprechend dem Formatstring (z.B. %d als ints, %f als floats),
// erwartet dabei Leerzeichen als Trennzeichen,
// und weist die einzelnen formatierten Zahlen den übergebenen Variablen m,n,x,y zu.






Testcode für fprintf_ und fgets_():

Code: Alles auswählen

/*
SD card: fprintf_() und fgets_()
ver 1.01
*/


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



// SD Card
#define SD_CSpin 38  //  <<<<<<<<<<<<<<<<<<<<<< adjust !!

File myFile;
char fname[64];

char sdata[128];
char sbuf[128];



int32_t fprintf_ ( File * stream, const char fmtstr[], ... ) {
   char      str[1024];
   va_list   args;
   int32_t   num;
   
   va_start( args, fmtstr );
   num = vsnprintf(str, sizeof(str), fmtstr, args);
   stream->print(str);
   va_end( args );

   return num;
}




char * fgets_ ( char * str, int32_t num, File * stream ) {
  int32_t i = 0;

  strcpy(str, "");
  while ( (stream->available()) && (i < num-1) ) {
    int16_t ch = stream->read();
    if (ch < 0)     // end of file
      break;
    str[i++] = ch;
    if ('\n' == ch) // end of line
      break;
  }

  if (i) {          // room in buffer for terminating null
    str[i] = 0;
    return str;
  }
  else
  // return NULL;                  // buffer too small or immediate end of file
  { strcpy(str, ""); return str; } // alternative: return ""
}





void setup()
{
  int16_t  p, i, cnt;
  float    x;
  char     sval[20];
  int16_t  ival;
  double   fval;
 
  pinMode(SD_CSpin, OUTPUT); 
  Serial.begin(115200);
   
  sprintf(sbuf,"#: SD Initializing... ");
  Serial.println(sbuf); 

  while(!SD.begin(SD_CSpin) ) {
    sprintf(sbuf,"#: ...SD init failed ");
    Serial.println(sbuf);
    delay(1000);
  }
 
  sprintf(sbuf,"#: ...SD OK !      ");
  Serial.println(sbuf); 
  strcpy(fname,"test.txt");
 
  if (SD.exists(fname) ) {
    sprintf(sbuf,"#: %s exists     ",fname);
    Serial.println(sbuf); 
   
    sprintf(sbuf,"#: Removing %s      ",fname);   
    Serial.println(sbuf);
   
    SD.remove("test.txt");
    // removed: success ?
    if (SD.exists(fname) ) {
       sprintf(sbuf,"#: %s  exists     ",fname); 
       Serial.println(sbuf); 
    }
    else {
       sprintf(sbuf,"#: %s  N/A     ",fname); 
       Serial.println(sbuf); 
     }
  }
   
 
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another. 
  myFile = SD.open(fname, FILE_WRITE);
 
  if (myFile) {
    // if the file opened okay, write to it, then close file:
    sprintf(sbuf,"#: Writing strings to %s ",fname);
    Serial.println(sbuf);
   
    //---------------------------------------------------------------------------------
    // write data to file
    fprintf_(&myFile, "%s\n%d\n%d\n%f\n%f\n", "Teststring", 1, 2, PI, 4.567890);   
    //---------------------------------------------------------------------------------
   
    // close the file:
    myFile.close();
    sprintf(sbuf,"#: %s closed.   ",fname);
    Serial.println(sbuf); 
  } 
  else {
    // if the file didn't open, print an error:
    sprintf(sbuf,"#: error opening %s   ",fname);
    Serial.println(sbuf);     
  }
 
  Serial.println();
  // re-open the file for reading:
  myFile = SD.open(fname);
  if (myFile) {
    sprintf(sbuf,"#: reading %s ",fname);
    Serial.println(sbuf); 
   
    // read from the file until there's nothing else in it:
    i=0;
    cnt=1;   
   
    while (myFile.available()) {
      strcpy(sdata, "");
      fgets_ ( sdata, 20, &myFile ); 
      Serial.print(cnt); Serial.print(": string raw="); Serial.println(sdata);
      Serial.println("rueckformatiert:");
      if (cnt==1) {Serial.print("str  ="); Serial.println(sdata); }
      if (cnt==2) {Serial.print("int  ="); Serial.println(atoi(sdata) ); }
      if (cnt==3) {Serial.print("int  ="); Serial.println(atoi(sdata) ); }
      if (cnt==4) {Serial.print("float="); Serial.println(atof(sdata) ); }
      if (cnt==5) {Serial.print("float="); Serial.println(atof(sdata) ); }
      ++cnt;
    } 
   
    // close the file:
    myFile.close();       
    sprintf(sbuf,"#: %s closed. ",fname);
    Serial.println(sbuf);     
  } else {
    // if the file didn't open, print an error:
    sprintf(sbuf,"#: error opening %s   ",fname);     
    Serial.println(sbuf);

  }
}

void loop()
{
  // nothing happens after setup
}





Testcode für fprintf_() und fscanf_():

Code: Alles auswählen

/*
SD card: fprintf_() und fscanf_()
ver 0.04
*/

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


// SD Card
#define SD_CSpin 38  //  <<<<<<<<<<<<<<<<<<<<<< adjust !!
File myFile;
char fname[64];

char sdata[128];
char sbuf[128];



//********************************************************************************​*********** 
int32_t  fscanf_ ( File * stream, const char fmtstr[], ... ) {
   const  int32_t   MAXSTRSIZE = 1024;
   char   str[MAXSTRSIZE];
   va_list   args; 
   int32_t   i=0, cnt=0;
   int16_t   chr;
 
   va_start(args, fmtstr);
 
   strcpy(str, "");
   while ( (stream->available()) && (i < MAXSTRSIZE-1) ) {   
      chr = stream->read() ;
      if (chr>=0 && chr!='\n') {
           str[i]=(char)chr;     
           ++i;
      }
      else break;     
   } 
 
   str[++i] = '\0';
   cnt = vsscanf ( str, fmtstr, args ); 
   va_end(args);

   return cnt;
}


//********************************************************************************​*********** 

int32_t  fprintf_ ( File * stream, const char fmtstr[], ... ) {
   char      str[1024];
   va_list   args;
   int32_t   num;
   
   va_start( args, fmtstr );
   num = vsnprintf(str, sizeof(str), fmtstr, args);
   stream->print(str);
   va_end( args );
   
   return num;
}

//********************************************************************************​*********** 


void setup()
{
  int32_t  p, i, cnt;
  char     sval[20];
  int32_t  ival, n, m;
  float   fval, x, y;
  // alternativ, ohne jeden Effekt: float   fval, x, y;

  pinMode(SD_CSpin, OUTPUT); 
  Serial.begin(9600);
 
  sprintf(sbuf,"#: SD Initializing... ");
  Serial.println(sbuf); 

  while(!SD.begin(SD_CSpin) ) {
    sprintf(sbuf,"#: ...SD init failed ");
    Serial.println(sbuf);
    delay(1000);
  }
 
  sprintf(sbuf,"#: ...SD OK !      ");
  Serial.println(sbuf); 
  strcpy(fname,"test.txt");
 
  if (SD.exists(fname) ) {
    sprintf(sbuf,"#: %s exists     ",fname);
    Serial.println(sbuf); 
   
    sprintf(sbuf,"#: Removing %s      ",fname); 
    Serial.println(sbuf);
   
    SD.remove("test.txt");
    // removed: success ?
    if (SD.exists(fname) ) {
       sprintf(sbuf,"#: %s  exists     ",fname); 
       Serial.println(sbuf); 
    }
    else {
       sprintf(sbuf,"#: %s  N/A     ",fname); 
       Serial.println(sbuf); 
     }
  }
   


 
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another. 
  myFile = SD.open(fname, FILE_WRITE);
 
  if (myFile) {
    // if the file opened okay, write to it, then close file:
    sprintf(sbuf,"#: Writing strings to %s ",fname);
    Serial.println(sbuf);
   
    //---------------------------------------------------------------------------------
    // write data to file
    fprintf_(&myFile, "%d %d %f %f\n",  1, 2, PI, 4.567890);   
    //---------------------------------------------------------------------------------
 
    // close the file:
    myFile.close();
    sprintf(sbuf,"#: %s closed.   ",fname);
    Serial.println(sbuf); 
  } 
  else {
    // if the file didn't open, print an error:
    sprintf(sbuf,"#: error opening %s   ",fname);
    Serial.println(sbuf);     
  }
 
 
 
 
 
  // re-open the file for reading:
  Serial.println();
 
  myFile = SD.open(fname);
  if (myFile) {
    sprintf(sbuf,"#: reading %s ",fname);
    Serial.println(sbuf); 
   
    // read from the file until there's nothing else in it:
    i=0;
    cnt=0; 
    strcpy(sdata, "");
   
    //---------------------------------------------------------------------------------
    cnt = fscanf_(&myFile, "%d %d %f %f", &m, &n, &x, &y);
    //---------------------------------------------------------------------------------
                           
    Serial.println("# nach Aufruf cnt=fscanf_ im Hauptprogramm");   
       // Testausgabe:
       Serial.print("returned cnt="); Serial.println(cnt);   
       Serial.println();
       Serial.println("returned reformatted variables m,n,x,y:");
       Serial.println(m);
       Serial.println(n);
       Serial.println(x);
       Serial.println(y);

   
    // close the file:
    myFile.close();       
    sprintf(sbuf,"#: %s closed. ",fname);
    Serial.println(sbuf);     
  } else {
    // if the file didn't open, print an error:
    sprintf(sbuf,"#: error opening %s   ",fname);     
    Serial.println(sbuf);

  }
}

void loop()
{
  // nothing happens after setup
}






Zu guter Letzt hier die komplette lib, die man in eigene Sketche #includen kann:

Code: Alles auswählen

// Library: ardustdio.h
// kind of stdio.h functionality for files plus extended C-string manipulation
//
// (C) Helmut Wunder (HaWe) 2015
// freie Verwendung für private Zwecke
// für kommerzielle Zwecke nur nach Genehmigung durch den Autor.
// Programming language: Arduino Sketch C/C++ (IDE 1.6.1 - 1.6.3)
// protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// http://creativecommons.org/licenses/by-nc-sa/3.0/   //   




#ifndef  ARDUSTDIO_H
#define ARDUSTDIO_H

/*

long     fprintf_( File * stream, const char fmtstr[], ... );       // see ANSI C: fprintf()
long     fscanf_ ( File * stream, const char fmtstr[], ... ) ;      // see ANSI C: fscanf()
char   * fgets_  ( char * str, int32_t num, File * stream );        // see ANSI C: fgets()
File     fopen_  ( char * filename, const char * mode );            // see ANSI C: fopen()
int16_t  fclose_ ( File   file_);                                   // see ANSI C: fclose()   
int16_t  remove_ ( char * filename );                               // see ANSI C: remove()
 

char  * ftoa( char * str, double f, int16_t precision );            // converts float to string by precision (digits)

char  * strinsert( char * source, char * sub, int pos );            // insert a substr into a string at pos
char  * strdelnpos(char * source, int16_t  pos, int16_t  sublen);   // delete a substr in string at pos
char  * strpatch ( char * source, char * sub, int pos );            // patch string by substr at pos
char  * substr  (  char * source, char * sub, int pos, int len );   // get substring of source string at pos by length
int16_t strchpos(  char * str, char ch );                           // find 1st occurence of char ch in string str
int16_t strstrpos( char * haystack,  char * needle)                 // find 1st occurance of substr in str
char  * stradd(char * s, int n, ...)  // "adds strings" s=sumstring , n=number_in_list, ... = var string list




*/


#define fileIO_OK            +1
#define fileIO_NO_ERR         0
#define fileIO_ERR_CREATE    -1
#define fileIO_ERR_OPEN      -2
#define fileIO_ERR_REMOVE    -3
#define fileIO_ERR_WRITE     -4
#define fileIO_ERR_READ      -5
#define fileIO_ERR_IMPLAUS   -6
#define fileIO_ERR_NAME      -8
#define fileIO_ERR_SDCARD   -16


//********************************************************************************************
#if defined (__arm__) && defined (__SAM3X8E__) // Arduino Due compatible

int32_t  fscanf_ ( File * stream, const char fmtstr[], ... ) {         // see ANSI C: fscanf()
   const  int32_t   MAXSTRSIZE = 1024;
   char   str[MAXSTRSIZE];
   va_list   args;
   int32_t   i=0, cnt=0;
   int16_t   chr, argcnt=0;
   char      argstart, ch;
 
   va_start(args, fmtstr);
   strcpy(str, "");
   while ( (stream->available()) && (i < MAXSTRSIZE-1) ) {   
      chr = stream->read() ;
     
      if (chr>=0 && chr!='\n') {  // additionally limit to number of arguments! <<<<<<<<
           ch = (char)chr; 
           str[i] = ch;     
           ++i;
      }
      else break;     
   } 
   str[++i] = '\0';                                                         
   cnt = vsscanf( str, fmtstr, args );
   va_end(args);

   return cnt;
}
#endif

//********************************************************************************************

int32_t fprintf_ ( File * stream, const char fmtstr[], ... ) {          // see ANSI C: fprintf()
   const  int32_t   MAXSTRSIZE = 1024;
   char   str[MAXSTRSIZE];
   va_list   args;
   int32_t   num;
   
   va_start( args, fmtstr );
   num = vsnprintf(str, sizeof(str), fmtstr, args);
   stream->print(str);
   va_end( args );

   return num;
}

//********************************************************************************************



char * fgets_ ( char * str, int32_t num, File * stream ) {              // see ANSI C: fgets()
  int32_t i = 0;

  strcpy(str, "");
  while ( (stream->available()) && (i < num-1) ) {
    int16_t ch = stream->read();
    if (ch < 0)     // end of file
      break;
    str[i++] = ch;
    if ('\n' == ch) // end of line
      break;
  }

  if (i) {          // room in buffer for terminating null
    str[i] = 0;
    return str;
  }
  else
  // return NULL;                  // buffer too small or immediate end of file
  { strcpy(str, ""); return str; } // alternative: return ""
}


//********************************************************************************************


File fopen_(char * filename, const char * mode) {                      // see ANSI C: fopen()
   int16_t  IOresult=0;
   File     file_ ;     // can't be initialized to NULL !
 
   if(mode=="w") {                               // remove/rewrite
      IOresult = SD.remove(filename);            // success==TRUE, failed==FALSE
      file_    = SD.open(filename, FILE_WRITE); 
   } 
   else
   if(mode=="a") {                               // append at EOF
      file_  = SD.open(filename, FILE_WRITE); 
   }
   else
   if(mode=="r") {
      file_  = SD.open(filename, FILE_READ);      // open at beginning of file
   }
   return file_; 
}


//********************************************************************************************

int16_t   fclose_(File file_) {                                      // see ANSI C: fclose()
   file_.close();
   return fileIO_NO_ERR ;
}   

//********************************************************************************************

int16_t  remove_ (char * filename) {                                 // see ANSI C: remove()
   int16_t  IOresult=0;

   if (SD.exists(filename) ) {       
       IOresult=SD.remove(filename);       
       // removed: success ?
       if (IOresult) return fileIO_NO_ERR;                 // SD file remove OK
       else  return fileIO_ERR_REMOVE;                     // SD file remove failed   
    }
    else    return fileIO_ERR_NAME;                        // SD file name not found 
}

//********************************************************************************************


char * ftoa(char * str, double f, int16_t precision) { // convert float to string by precision (digits)
  int32_t  p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
  int32_t  intnum, decimal;
 
  char * sret = str;

  if(precision>8) precision=8;
 
  intnum = (long)f;
  itoa( intnum, str, 10);
 
  while ( *str != '\0') str++;
  *str++ = '.';
 
  decimal = abs( (long)( (f - intnum ) * p[precision]) ); 
  itoa( decimal, str, 10);

  return sret;
}


//********************************************************************************************

char * strinsert(char * source, char * sub, int16_t  pos) {  // insert a substr into a string at pos
   int   srclen, sublen;
   char  * sret = source;

   srclen = strlen(source);
   sublen = strlen(sub);

   if( pos>srclen ) pos=srclen;
   memmove( source+pos+sublen, source+pos, sublen+srclen-pos );
   memcpy ( source+pos, sub, sublen );

   source[srclen+sublen]= '\0';
   return sret;
   



//********************************************************************************************

char * strdelnpos( char * source, int16_t  pos, int16_t  sublen ) {  // delete a substr in string at pos
   int   srclen;
   char  * sret = source;

   srclen = strlen(source);

   if( pos > srclen ) return sret;
   if( sublen > srclen-pos ) sublen = srclen-pos;
   memmove( source+pos, source+pos+sublen, srclen+sublen);
   source[srclen-sublen]= '\0';
   return sret;
   
}   
 


//********************************************************************************************

char * strpatch( char * source, char * sub, int16_t  pos )  {  // patch string by substr at pos
   int16_t srclen, sublen;
   char  * sret = source;
   
   srclen = strlen(source);
   sublen = strlen(sub);
   
   if( pos+sublen > srclen) return sret;   // size/position error
   memcpy(source+pos, sub, sublen);   

   return sret; 
   
}



//********************************************************************************************

char  * substr  ( char * source, char * sub, int16_t  pos, int16_t len ) { // get substr of source at pos by length
   char   *sret = sub;

   if ( (pos+len) >  strlen(source) ) len = strlen(source)-pos;  // cut away if too long
   sub = strncpy(sub, source+pos, len);
   sub[len] = '\0';
 
   return sret; 
}




//********************************************************************************************

int16_t strchpos( char * str, char ch ) {       // find 1st occurence of char ch in string str
   int16_t  len, i=-1;
   
   len=strlen(str);
   if(len==0) return i;
   for(i=0; i<len; ++i) {
     if(str[i]==ch) break;   
   }   
   return i;
}   




//********************************************************************************************


int16_t  strstrpos(char * haystack,  char * needle)   // find 1st occurance of substr in str
{
   char *p = strstr(haystack, needle);
   if (p) return p - haystack;
   return -1;   // Not found = -1.
}


//********************************************************************************************

char * stradd(char * s, int n, ...)  // "adds strings" s=sumstring , n=number_in_list, ... = var string list
{
    va_list vlst;   
    int i;
   
    char * bufptr;
    char * retptr = s;
   
    va_start(vlst, n);
    for (i=1; i<=n; ++i)   {
       bufptr = va_arg(vlst, char *);
       strcat(s, bufptr);
    }
    va_end(vlst);   
    return retptr;   
}


//********************************************************************************************


#endif


share and enjoy! :cool:

Helmut Wunder ( HaWe) hat geschrieben:für alle hier veröffentlichten Software-Source-Codes gilt:
/*
// (C) Helmut Wunder (HaWe) 2015
// freie Verwendung für private Zwecke
// für kommerzielle Zwecke nur nach Genehmigung durch den Autor.
// Programming language: Arduino Sketch C/C++ (IDE 1.6.1 - 1.6.3)
// protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// http://creativecommons.org/licenses/by-nc-sa/3.0/
*/

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C

Beitragvon HaWe » 9. Jul 2015 18:56

(Platzhalter)

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C, UART...

Beitragvon HaWe » 9. Jul 2015 19:22

Platzhalter

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C,...

Beitragvon HaWe » 13. Jul 2015 19:51

(Platzhalter)

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C,...

Beitragvon HaWe » 13. Jul 2015 19:51

(Platzhalter)

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C, UART,...

Beitragvon HaWe » 13. Jul 2015 20:48

Platzhalter

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C, UART,...

Beitragvon HaWe » 13. Jul 2015 20:51

HC-05 : serielle BT-Module
( als Master oder Slave konfigurierbar )


Bild Bild
Bild

baudrate: 9600 - 115200; default-baudrate: 38400


Drahtlosverbindung über zwei HC-05 Module:
Quelle: http://www.ebay.de/itm/Bluetooth-Modul-HC-05-Master-Slave-UART-fur-z-B-Arduino-inkl-Adapterboard-/291672244026?hash=item43e9053f3a:g:DlwAAOSwabhUVUBi
(Herr Niesen ist sehr hilfsbereit bezüglich Rückfragen und Konfigurationsproblemen!)


Achtung: verträgt nur 3,3V UART Signal-Level, nicht 5V-kompatibel!
Spannungsversorgung dagegen ist immer 5V!
D.h.: mit Raspi und Arduino DUE läuft es direkt, für Arduino MEGA werden 5V -> 3,3V Levelshifter benötigt!

Durchführung:
1 HC-05 Modul als Master konfigurieren, das andere als Slave.
BAUD Rate richtig konfigurieren (ich verwende durchweg 115200 baud).
Dann diese beiden Module miteinander pairen und die UART-RX/TX Pins über Kreuz mit Raspi bzw. Arduino verbinden:
HC-05 <-> 5V Vc und GND
Master-Seite:
Arduino GND <-> HC-05 GND
Arduino RX0 <-> HC-05 TX
Arduino TX0 <-> HC-05 RX
Slave-Seite:
HC-05 GND <-> Slave GND
HC-05 RX <-> Slave TX
HC-05 TX <-> Slave RX
Keine weiteren Einstellungen nötig - läuft automatisch als wäre ein langes Kabel dazwischen.

Links z.B.:
http://www.ebay.de/itm/Bluetooth-Modul-HC-05-Master-Slave-UART-fur-z-B-Arduino-inkl-Adapterboard-/291672244026?hash=item43e9053f3a:g:DlwAAOSwabhUVUBi
http://www.brunwinkel.de/elektronik/module/btm400_6b/
http://www.exp-tech.de/serial-port-bluetooth-module-master-slave-hc-05

Konfiguration per AT-Befehle über die serielle Arduino-Konsole (selbe baudrate einstellen wie HC-05!)
Enable-Pin an 3.3V > ermöglicht Programmieren im AT Modus :

Code: Alles auswählen

 

# at
OK


# at+orgl        //auf werkseinstellungen zurück
OK


# at+addr?        //adreese?
+ADDR:98d3:31:b1426e
OK


# at+state?        //zustand?
+STATE:INITIALIZED
OK


# at+role?        //rolle? master=1, slave=0
+ROLE:0
OK


# at+pswd?        //password?
+PSWD:1234
OK


# at+name?        //name?
+NAME:H-C-2010-06-01
OK


# at+uart?
+UART:38400,0,0
OK


# at+bind?
+BIND:0:0:0
OK


# at+cmode?
+CMOD:0
OK




# -----
master:
#------

# at+name=master_RP6
OK


# at+pswd=0000
OK


# at+role=1
OK


# at+reset
OK


# at+init
OK


# at+pair=98d3,31,b1f2b2,20
OK


# at+bind=98d3,31,b1f2b2
OK
 









#---------
slave
#--------


# at
OK


# at+orgl
OK


# at+addr?
+ADDR:98d3:31:b1f2b2
OK


# at+role?
+ROLE:0
OK


# at+name?
+NAME:H-C-2010-06-01
OK


# at+uart?
+UART:38400,0,0
OK


# at+pswd?
+PSWD:1234
OK
--------------------------------------
--------------------------------------
# at+name=slave_RP6
OK
# at+pswd=0000
OK
( zit. nach Inka, Roboternetz-Forum)

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C, UART,...

Beitragvon HaWe » 13. Jul 2015 20:51

Platzhalter

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C, UART,...

Beitragvon HaWe » 13. Jul 2015 20:56

Bei Problemen mit 5V-Geräten an 3.3V UART Bus -
einfacher Spannungsteiler:


Code: Alles auswählen

Arduino TX --|   ( 5V Level )
             |
            33k
             |
             |---- DEVICE RX ( 3.3V Level)
             |
            47k
             |
            GND

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C, UART,...

Beitragvon HaWe » 22. Jul 2015 20:57

Platzhalter

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C, UART,...

Beitragvon HaWe » 22. Jul 2015 21:00

Serial UART Lib: Kommunikation zwischen 2 Arduinos:

(die lib wurde auch extra so erstellt, um für die Display-Anzeige mit verschiedensten TFTs zu arbeiten; der Sketch ist für Mega und Due wegen Hardware-Serial Rx1/Tx1 usw., wird aber auch per SoftwareSerial auf Unos laufen (von anderem user getestet).
Standardmäßig hier UART-Übertragung mit 115200 baud.


Achtung:
Arduino AVRs (5V) und ARMs (3.3V) nicht ohne Levelshifter untereinander verbinden!

Code: Alles auswählen

/*     Tx master     
       ver 0006.64
       IDE 1.6.5
 */
 
#include <SPI.h>
#include <SD.h>
#include <UTFT.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9340.h>


#define  clock()  millis()


//=====================================================================================
// TFT LCD
//=====================================================================================
#define   UTFT_SmallFont     8 // UTFT 8x10
#define   UTFT_MediumFont   12 // UTFT ++
#define   UTFT_BigFont      18 // UTFT +++
#define   _SmallFont_        1 // 9341 6x9
#define   _MediumFont_       2 // 9341 12x16
#define   _BigFont_          3 // 9341 18x23

int16_t  LCDmaxX , LCDmaxY ;                // display size
int16_t  _curx_, _cury_,                    // last x,y cursor pos on TFT screen
         _maxx_, _maxy_;                    // max. x,y cursor pos on TFT screen       
char     wspace[128];                       // line of white space


// set LCD TFT type
int16_t  LCDTYPE   =   -1;


#define  _UTFT_       4  // Henning Karlsen UTFT 2.2-2.4" 220x176 - 320x240 lib
                           // http://henningkarlsen.com/electronics/library.php?id=51   //
#define _ILI9341_     8  // https://github.com/adafruit/Adafruit_ILI9340
                           // https://github.com/adafruit/Adafruit-GFX-Library //
                           
                           
//--------------------------------------------------------------------------------------------------
#define  UTFT_cs      52    // <<<<<<<< adjust!

//UTFT   qdUTFT(Model, SDA=MOSI,  SCL, CS,         RESET,  RS)    // Due: 3 exposed SS pins: 4,10,52
  UTFT   qdUTFT(QD220A,   A2,     A1,  A5,         A4,     A3);   // adjust model parameter and pins!
//UTFT   qdUTFT(QD220A,   50,     49,  UTFT_cs,  0,     51);   // A0->Vc (LED), A4->BoardReset
 extern  uint8_t SmallFont[];
//--------------------------------------------------------------------------------------------------
#define    tft_cs     50
#define    tft_dc     49
#define    tft_rst     0
Adafruit_ILI9340   tft = Adafruit_ILI9340(tft_cs, tft_dc, tft_rst);

//--------------------------------------------------------------------------------------------------

int16_t  fontwi= 8;  // default
int16_t  fonthi=10;  // default


void putfonttype(uint8_t fsize) {
  if(LCDTYPE==_UTFT_)  { fontwi= qdUTFT.getFontXsize(); fonthi=qdUTFT.getFontYsize(); }
  else
  if(fsize==_SmallFont_)     { fontwi= 6; fonthi=9; }  // 5x7 + overhead ?
  else
  if(fsize==_MediumFont_)    { fontwi=12; fonthi=16; } // ?
  else
  if(fsize==_BigFont_)       { fontwi=18; fonthi=23; } // ?
 
  _maxx_ = LCDmaxX / fontwi;    // max number of letters x>>
  _maxy_ = LCDmaxY / fonthi;    // max number of letters y^^
  memset(wspace, ' ', _maxx_);  // line of white space
  wspace[_maxx_]='\0';
}



void setlcdorient(int8_t orient) {
  if(LCDTYPE==_ILI9341_) {
      tft.setRotation(orient);
      LCDmaxX=tft.width();
      LCDmaxY=tft.height();       
   }
}

void lcdcls()  {                                                         
   if(LCDTYPE==_UTFT_)      { qdUTFT.clrScr();                } 
   if(LCDTYPE==_ILI9341_)   { tft.fillScreen(ILI9340_BLACK);  }
   _curx_ =0;  _cury_ =0;
}

void curlf()   {                                                       
   _curx_=0;
   if( _cury_ <=(LCDmaxY-10) ) _cury_+=fonthi;
   else _cury_=0;   
   if(LCDTYPE==_ILI9341_)   {tft.setCursor(0, _cury_); } 
}



void curxy(int16_t  x,  int16_t  y) {
   _curx_ = x;
   _cury_ = y;
   if(LCDTYPE==_ILI9341_)   {tft.setCursor(x, y); }
}


void lcdprintxy(int16_t x, int16_t y, char * str) {
   if(LCDTYPE==_UTFT_)     { qdUTFT.print(str,x,y); _curx_=x+strlen(str)*fontwi; _cury_=y; }
   else if(LCDTYPE==_ILI9341_)  {
      tft.setCursor(x,y);  tft.print(str);
      _curx_=tft.getCursorX(); _cury_=tft.getCursorY();
   }
}


void lcdprint(char * str) {
    if(LCDTYPE==_UTFT_)     { qdUTFT.print(str, _curx_, _cury_); _curx_=_curx_+strlen(str)*fontwi; }
    else if(LCDTYPE==_ILI9341_)  {
       tft.setCursor(_curx_, _cury_); tft.print(str);
       _curx_=tft.getCursorX(); _cury_=tft.getCursorY();
    }
}


void initlcd(uint8_t orient) { // 0,2==Portrait  1,3==Landscape
   if(LCDTYPE==_UTFT_) {
      qdUTFT.InitLCD();
      LCDmaxX=qdUTFT.getDisplayXSize();
      LCDmaxY=qdUTFT.getDisplayYSize();
      qdUTFT.setFont(SmallFont);
      putfonttype(UTFT_SmallFont);
      fontwi=qdUTFT.getFontXsize();
      fonthi=qdUTFT.getFontYsize();
   }
   else
   if(LCDTYPE==_ILI9341_) {
      tft.begin();
      setlcdorient(orient);       
      tft.setTextSize(_SmallFont_);
      putfonttype(_SmallFont_);
   }   




//=====================================================================================
//=====================================================================================

const    uint8_t  MSGSIZE=64;
uint8_t  bsync=255;
uint8_t  sendbuf[MSGSIZE];
uint8_t  recvbuf[MSGSIZE];


//=====================================================================================
const uint32_t UARTclock=115200;  // 

void setup() {
   char sbuf[128];   
   int32_t  i=0;
         
   // Serial
   Serial.begin(115200);   // USB terminal (UART 0)
 
   Serial1.begin(UARTclock);                    // RX1-TX1 (UART 1)
   while(Serial1.available())  Serial1.read();  // clear output buffer

     
   // TFT LCD
   Serial.println();
   LCDTYPE = _UTFT_;
   Serial.print("init LCD...");
   initlcd(1);   
   Serial.println(" done.");   lcdcls();
   sprintf(sbuf, "LCD=%d wi%d x hi%d",LCDTYPE,LCDmaxX,LCDmaxY);
   Serial.println(sbuf);
   Serial.println();
   lcdcls(); lcdprint(sbuf);
   
   sprintf(sbuf, "setup(): done.");
   Serial.println(); Serial.println(sbuf);   
   curlf(); curlf(); lcdprint(sbuf);

   lcdcls();
   
   sprintf(sbuf, "Tx master, BAUD= %ld", UARTclock );;
   lcdprintxy(0, 0, sbuf);


}



//=====================================================================================
//=====================================================================================

void displayvalues(int line, char * caption, uint8_t array[]) {
  int cnt;
  char sbuf[128];
 
  sprintf(sbuf, "%s cks=%-4d", caption, array[1]);
  lcdprintxy(0, line, sbuf); 
  //Serial.println(sbuf);
  for(cnt=0; cnt<8; ++cnt) {
    sprintf(sbuf, "%3d ", array[cnt]);      // print on TFT
    lcdprintxy(cnt*3*8, line+10, sbuf);
    //Serial.print(sbuf);                      // Print sendbuffer to the Serial Monitor
  }   
  //Serial.println(); 
 


//=====================================================================================
//=====================================================================================
// serial TCP

uint8_t calcchecksum(uint8_t array[]) {
   int32_t  sum=0;
   for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
   return (sum & 0x00ff);
}

bool checksumOK(uint8_t array[]){
   return (calcchecksum(array)==array[1]);
}

// ================================================================
// addToBuffer and receive function courtesy of chucktodd

bool addToBuffer( uint8_t buf[], uint8_t *cnt, uint16_t timeout){
bool inSync = *cnt>0;
unsigned long start=millis();
while((*cnt<MSGSIZE)&&(millis()-start<timeout)){
  if(Serial1.available()){ // grab new char, test for sync char, if so start adding to buffer
    buf[*cnt] = (uint8_t)Serial1.read();
    if(inSync) *cnt += 1;  // my origional *cnt++ was updating the pointer address, not
                           // the pointed to sendbuffer
    else{
     if(buf[*cnt]==0xFF){
       inSync = true;
       *cnt +=1;
       }
     }
    }
  }
return (*cnt==MSGSIZE);
}


//=====================================================================================

bool receive(uint8_t * buf, uint16_t timeout, uint8_t *cnt){ // by passing cnt in and out,
// i can timeout and still save a partial buffer, so a resync costs less (less data lost)

bool inSync=false;
unsigned long start=millis();
uint8_t * p;  // pointer into buf for reSync operation
bool done=false;

do{
  done = addToBuffer(buf,cnt,timeout); // if this return false, a timeout has occured, and the while will exit.
  if(done){ // do checksumOK test of buffer;
    done=checksumOK(buf);
    if(!done){// checksumOK failed, scan buffer for next sync char
       p = (uint8_t*)memchr((buf+1),0xff,(MSGSIZE-1)); //forgot to skip the current sync at 0
       
       
       if(p){ // found next sync char, shift buffer content, refill buffer
         *cnt = MSGSIZE -(p-buf); // count of characters to salvage from this failure
         memcpy(buf,p,*cnt); //cnt is now where the next character from Serial is stored!
         }
       else *cnt=0; // whole buffer is garbage
       }
    }
   
  }while(!done&&(millis()-start<timeout));

return done; // if done then buf[] contains a sendbufid buffer, else a timeout occurred
}

//=====================================================================================
//=====================================================================================

void loop()

  char     sbuf[128],  resOK;   
  static   uint8_t cnt=0; 
  uint8_t  cbuf[MSGSIZE], chk;

 
  //   send to Rx slave Arduino
 
  //Serial.println(); 
  sendbuf[0]=bsync;
  sendbuf[1]=calcchecksum(sendbuf);
  for(uint8_t i=0; i<MSGSIZE; i++) {       
     Serial1.write(sendbuf[i]);                          // Send values to the Rx Arduino       
  }       
  //Serial1.flush();                                     // clear output buffer
  //displayvalues(20, "Transmitted...: ", sendbuf);
  sprintf(sbuf, "%4d %4d", sendbuf[4], sendbuf[6]);
  lcdprintxy(0, 20, sbuf);

 
  //     Receive from Rx slave Arduino

  memset(cbuf, 0, sizeof(cbuf)); 
   
  resOK = receive ( cbuf, 10000,&cnt);
 
  if( resOK ) {                         // byte 0 == syncbyte ?
    cnt=0;

    //displayvalues(60, "Received...:", cbuf);
     chk=(byte)calcchecksum(cbuf);     
     memcpy(recvbuf, cbuf, sizeof(cbuf));
 
        // change values to send back!
        memcpy(sendbuf, recvbuf, sizeof(sendbuf));         // copy inbuf to outbuf
        sendbuf[4]+=1;                                     // change [4] to send back
       
       
  }
 
}


//=====================================================================================
//=====================================================================================





Code: Alles auswählen

/*     Rx slave     
       ver 0006.64
       IDE 1.6.5
 */
 
#include <SPI.h>
#include <SD.h>
#include <UTFT.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9340.h>


#define  clock()  millis()


//=====================================================================================
// TFT LCD
//=====================================================================================
#define   UTFT_SmallFont     8 // UTFT 8x10
#define   UTFT_MediumFont   12 // UTFT ++
#define   UTFT_BigFont      18 // UTFT +++
#define   _SmallFont_        1 // 9341 6x9
#define   _MediumFont_       2 // 9341 12x16
#define   _BigFont_          3 // 9341 18x23

int16_t  LCDmaxX , LCDmaxY ;                // display size
int16_t  _curx_, _cury_,                    // last x,y cursor pos on TFT screen
         _maxx_, _maxy_;                    // max. x,y cursor pos on TFT screen       
char     wspace[128];                       // line of white space


// set LCD TFT type
int16_t  LCDTYPE   =   -1;

#define  _UTFT_       4  // Henning Karlsen UTFT 2.2-2.4" 220x176 - 320x240 lib
                           // http://henningkarlsen.com/electronics/library.php?id=51   //
#define _ILI9341_     8  // https://github.com/adafruit/Adafruit_ILI9340
                           // https://github.com/adafruit/Adafruit-GFX-Library //
                           
                           
//--------------------------------------------------------------------------------------------------
#define  UTFT_cs      52    // <<<<<<<< adjust!

//UTFT   qdUTFT(Model, SDA=MOSI,  SCL, CS,         RESET,  RS)    // Due: 3 exposed SS pins: 4,10,52
  UTFT   qdUTFT(QD220A,   A2,     A1,  A5,         A4,     A3);   // adjust model parameter and pins!
//UTFT   qdUTFT(QD220A,   50,     49,  UTFT_cs,  0,     51);   // A0->Vc (LED), A4->BoardReset
 extern  uint8_t SmallFont[];
//--------------------------------------------------------------------------------------------------
#define    tft_cs     50
#define    tft_dc     49
#define    tft_rst     0
Adafruit_ILI9340   tft = Adafruit_ILI9340(tft_cs, tft_dc, tft_rst);

//--------------------------------------------------------------------------------------------------

int16_t  fontwi= 8;  // default
int16_t  fonthi=10;  // default


void putfonttype(uint8_t fsize) {
  if(LCDTYPE==_UTFT_)  { fontwi= qdUTFT.getFontXsize(); fonthi=qdUTFT.getFontYsize(); }
  else
  if(fsize==_SmallFont_)     { fontwi= 6; fonthi=9; }  // 5x7 + overhead ?
  else
  if(fsize==_MediumFont_)    { fontwi=12; fonthi=16; } // ?
  else
  if(fsize==_BigFont_)       { fontwi=18; fonthi=23; } // ?
 
  _maxx_ = LCDmaxX / fontwi;    // max number of letters x>>
  _maxy_ = LCDmaxY / fonthi;    // max number of letters y^^
  memset(wspace, ' ', _maxx_);  // line of white space
  wspace[_maxx_]='\0';
}



void setlcdorient(int8_t orient) {
  if(LCDTYPE==_ILI9341_) {
      tft.setRotation(orient);
      LCDmaxX=tft.width();
      LCDmaxY=tft.height();       
   }
}

void lcdcls()  {                                                         
   if(LCDTYPE==_UTFT_)      { qdUTFT.clrScr();                } 
   if(LCDTYPE==_ILI9341_)   { tft.fillScreen(ILI9340_BLACK);  }
   _curx_ =0;  _cury_ =0;
}

void curlf()   {                                                       
   _curx_=0;
   if( _cury_ <=(LCDmaxY-10) ) _cury_+=fonthi;
   else _cury_=0;   
   if(LCDTYPE==_ILI9341_)   {tft.setCursor(0, _cury_); } 
}



void curxy(int16_t  x,  int16_t  y) {
   _curx_ = x;
   _cury_ = y;
   if(LCDTYPE==_ILI9341_)   {tft.setCursor(x, y); }
}


void lcdprintxy(int16_t x, int16_t y, char * str) {
   if(LCDTYPE==_UTFT_)     { qdUTFT.print(str,x,y); _curx_=x+strlen(str)*fontwi; _cury_=y; }
   else if(LCDTYPE==_ILI9341_)  {
      tft.setCursor(x,y);  tft.print(str);
      _curx_=tft.getCursorX(); _cury_=tft.getCursorY();
   }
}


void lcdprint(char * str) {
    if(LCDTYPE==_UTFT_)     { qdUTFT.print(str, _curx_, _cury_); _curx_=_curx_+strlen(str)*fontwi; }
    else if(LCDTYPE==_ILI9341_)  {
       tft.setCursor(_curx_, _cury_); tft.print(str);
       _curx_=tft.getCursorX(); _cury_=tft.getCursorY();
    }
}


void initlcd(uint8_t orient) { // 0,2==Portrait  1,3==Landscape
   if(LCDTYPE==_UTFT_) {
      qdUTFT.InitLCD();
      LCDmaxX=qdUTFT.getDisplayXSize();
      LCDmaxY=qdUTFT.getDisplayYSize();
      qdUTFT.setFont(SmallFont);
      putfonttype(UTFT_SmallFont);
      fontwi=qdUTFT.getFontXsize();
      fonthi=qdUTFT.getFontYsize();
   }
   else
   if(LCDTYPE==_ILI9341_) {
      tft.begin();
      setlcdorient(orient);       
      tft.setTextSize(_SmallFont_);
      putfonttype(_SmallFont_);
   }   




//=====================================================================================
//=====================================================================================

const    uint8_t  MSGSIZE=64;
uint8_t  bsync=255;
uint8_t  sendbuf[MSGSIZE];
uint8_t  recvbuf[MSGSIZE];


//=====================================================================================
const uint32_t UARTclock=115200

void setup() {
   char sbuf[128];   
   int32_t  i=0;
         
   // Serial
   Serial.begin(115200);   // USB terminal (UART 0)
 
   Serial1.begin(UARTclock);                    // RX1-TX1 (UART 1)
   while(Serial1.available())  Serial1.read();  // clear output buffer

     
   // TFT LCD
   Serial.println();
   LCDTYPE = _UTFT_;
   Serial.print("init LCD...");
   initlcd(1);   
   Serial.println(" done.");   lcdcls();
   sprintf(sbuf, "LCD=%d wi%d x hi%d",LCDTYPE,LCDmaxX,LCDmaxY);
   Serial.println(sbuf);
   Serial.println();
   lcdcls(); lcdprint(sbuf);
   
   sprintf(sbuf, "setup(): done.");
   Serial.println(); Serial.println(sbuf);   
   curlf(); curlf(); lcdprint(sbuf);

   lcdcls();
   
   sprintf(sbuf, "Rx slave, BAUD= %ld", UARTclock );;
   lcdprintxy(0, 0, sbuf);


}



//=====================================================================================
//=====================================================================================

void displayvalues(int line, char * caption, uint8_t array[]) {
  int cnt;
  char sbuf[128];
 
  sprintf(sbuf, "%s cks=%-4d", caption, array[1]);
  lcdprintxy(0, line, sbuf); 
  //Serial.println(sbuf);
  for(cnt=0; cnt<8; ++cnt) {
    sprintf(sbuf, "%3d ", array[cnt]);      // print on TFT
    lcdprintxy(cnt*3*8, line+10, sbuf);
    //Serial.print(sbuf);                      // Print sendbuffer to the Serial Monitor
  }   
  //Serial.println(); 
 


//=====================================================================================
//=====================================================================================
// serial TCP

uint8_t calcchecksum(uint8_t array[]) {
   int32_t  sum=0;
   for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
   return (sum & 0x00ff);
}

bool checksumOK(uint8_t array[]){
   return (calcchecksum(array)==array[1]);
}

// ================================================================
// addToBuffer and receive function courtesy of chucktodd

bool addToBuffer( uint8_t buf[], uint8_t *cnt, uint16_t timeout){
bool inSync = *cnt>0;
unsigned long start=millis();
while((*cnt<MSGSIZE)&&(millis()-start<timeout)){
  if(Serial1.available()){ // grab new char, test for sync char, if so start adding to buffer
    buf[*cnt] = (uint8_t)Serial1.read();
    if(inSync) *cnt += 1;  // my origional *cnt++ was updating the pointer address, not
                           // the pointed to sendbuffer
    else{
     if(buf[*cnt]==0xFF){
       inSync = true;
       *cnt +=1;
       }
     }
    }
  }
return (*cnt==MSGSIZE);
}


//=====================================================================================

bool receive(uint8_t * buf, uint16_t timeout, uint8_t *cnt){ // by passing cnt in and out,
// i can timeout and still save a partial buffer, so a resync costs less (less data lost)

bool inSync=false;
unsigned long start=millis();
uint8_t * p;  // pointer into buf for reSync operation
bool done=false;

do{
  done = addToBuffer(buf,cnt,timeout); // if this return false, a timeout has occured, and the while will exit.
  if(done){ // do checksumOK test of buffer;
    done=checksumOK(buf);
    if(!done){// checksumOK failed, scan buffer for next sync char
       p = (uint8_t*)memchr((buf+1),0xff,(MSGSIZE-1)); //forgot to skip the current sync at 0
       
       
       if(p){ // found next sync char, shift buffer content, refill buffer
         *cnt = MSGSIZE -(p-buf); // count of characters to salvage from this failure
         memcpy(buf,p,*cnt); //cnt is now where the next character from Serial is stored!
         }
       else *cnt=0; // whole buffer is garbage
       }
    }
   
  }while(!done&&(millis()-start<timeout));

return done; // if done then buf[] contains a sendbufid buffer, else a timeout occurred
}

//=====================================================================================
//=====================================================================================

void loop()

  char     sbuf[128],  resOK;   
  static   uint8_t cnt=0; 
  uint8_t  cbuf[MSGSIZE], chk;
  uint32_t xtime;
 

  //     Receive fromTx master Arduino

  memset(cbuf, 0, sizeof(cbuf)); 
   
  resOK = receive ( cbuf, 10000,&cnt);
 
  if( resOK ) {                                      // byte 0 == syncbyte ?
    cnt=0;

    //displayvalues(60, "Received...:", cbuf);
     chk=(byte)calcchecksum(cbuf);     
     memcpy(recvbuf, cbuf, sizeof(cbuf));
 
        // change values to send back!
        memcpy(sendbuf, recvbuf, sizeof(sendbuf));   // copy inbuf to outbuf
        sendbuf[4]+=1;                               // change [6] to send back 
        sendbuf[6]+=1;                               // change [6] to send back       
       
  }


 
  //   send to Tx master Arduino
 
  //Serial.println(); 
  sendbuf[0]=bsync;
  sendbuf[1]=calcchecksum(sendbuf);
  for(uint8_t i=0; i<MSGSIZE; i++) {       
     Serial1.write(sendbuf[i]);                      // Send value to the Rx Arduino       
  }       
  //Serial1.flush();                                 // clear output buffer
  //displayvalues(20, "Transmitted...: ", sendbuf);
  sprintf(sbuf, "%4d %4d", sendbuf[4], sendbuf[6]);
  lcdprintxy(0, 20, sbuf);

 
 
 
}


//=====================================================================================
//=====================================================================================

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: Baustelle: Arduino Driver libraries: Displays, SD, I2C, UART,...

Beitragvon HaWe » 15. Sep 2015 15:40

(Platzhalter)

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5398
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Arduino Driver libraries (Baustelle): Displays, SD, I2C, UART,...

Beitragvon HaWe » 15. Sep 2015 15:40

(Platzhalter)


Zurück zu „allgemeine / Nicht-Lego-Robotik und Elektronik“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 Gäste

Lego Mindstorms EV3, NXT und RCX Forum : Haftungsauschluss