Page 1 of 1

questions about wiringPi

Posted: Sat Oct 31, 2015 5:44 pm
by davenull
hey,
on Gordon Henderson's wiringPi website http://wiringpi.com/wiringpi-and-the-ra ... i-model-b/ it's written:
Do make sure you are using wiringPi Version 2.18 though.
by command
gpio -v
I get
gpio version 2.26
but even an update for 2.29 is available meanwhile.

I have a Raspi B+, what version should I use?

Re: questions about wiringPi

Posted: Sat Oct 31, 2015 7:49 pm
by DougieLawson
Use the version that's pre-installed. 2.26 > 2.18 and you probably don't need the cosmetic changes in v2.29.

Re: questions about wiringPi

Posted: Sat Oct 31, 2015 7:53 pm
by davenull
thanks! :)

Re: questions about wiringPi

Posted: Sat Oct 31, 2015 9:03 pm
by davenull
now the next question:

I'm trying to port my serial communication program between 2 Arduinos to exchange one of them (called "Tx master") by a Raspberry Pi.
The communication is performed at 115200 baud, 1N8.
This is my Arduino code for testing and debugging purposes which is working highly failsafe:

Code: Select all

//=====================================================================================
//=====================================================================================
const    uint32_t  UARTclock = 115200;
const    uint8_t   MSGSIZE   = 32;
uint8_t  bsync=255;
uint8_t  sendbuf[MSGSIZE];
uint8_t  recvbuf[MSGSIZE];

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

void setup() {
   char sbuf[128];   
   int32_t  i=0;
         
   // Serial: USB terminal
   Serial.begin(115200);   
 
   // Serial 1: RX-TX UART com
   Serial1.begin(UARTclock);                   
   while(Serial1.available())  Serial1.read();  // clear output buffer
   
   sprintf(sbuf, "Tx master, BAUD= %ld", UARTclock );;
   Serial.print(sbuf);

}



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


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]);
}

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

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
  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;

     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       
       
  }
 
}
The code for the Arduino "Rx slave" is actually the same and will stay as it is, just send/receive is working vice versa:
first waiting to receive from Tx, and then sending different values back.


Now I unfortunately can't find a complete source code example for serial communicaion by wiringPi in the Resources or at github, both for sending and receiving alternatively, from the scratch:
https://projects.drogon.net/raspberry-p ... l-library/
https://github.com/WiringPi/WiringPi/bl ... ngSerial.h

what I have already done is changing the UART board settings in /boot/cmdline.txt by deleting
console=ttyAMA0,115200
in the line
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

saved,
then reboot.

can someone please show me a link to a basic complete code example for a UART send/receive program (just using the basic init, setup, serial write, read, and available() functions) ?

Re: questions about wiringPi

Posted: Sun Nov 01, 2015 9:22 am
by davenull
e.g., for the start:

what is *device ? How is the serialOpen function to be used?
int serialOpen (char *device, int baud) ;

is this correct?

char * uart;
int ioerr = serialOpen (uart, 115200); // what is *uart? how has it to be initialized? or nothing?

Re: questions about wiringPi

Posted: Sun Nov 01, 2015 9:29 am
by joan
The UART is /dev/ttyAMA0.

Other serial devices plugged in via USB dongles tend to be called /dev/ttyUSB0, /dev/ttyUSB1 etc.

Re: questions about wiringPi

Posted: Sun Nov 01, 2015 9:36 am
by davenull
thank you for your reply!

(edit:)
so this way...?

char Serial1[] = "/dev/ttyAMA0"; // for code compatibility reasons, for the start...
int ioerr = serialOpen (Serial1, 115200);

Re: questions about wiringPi

Posted: Sun Nov 01, 2015 9:41 am
by joan
davenull wrote:thank you for your reply!

(edit:)
so this way...?

char uart[] = "/dev/ttyAMA0";
int ioerr = serialOpen (uart, 115200);
Personally I'd use

Code: Select all

char *uart = "/dev/ttyAMA0";
int ioerr = serialOpen (uart, 115200);
or

Code: Select all

int ioerr = serialOpen ("/dev/ttyAMA0", 115200);
But that is just a matter of taste.

Re: questions about wiringPi

Posted: Sun Nov 01, 2015 9:48 am
by davenull
thanks, now I slowly get it..
The return value is the file descriptor
so it's not just an error to be returned, but also a file handle, correct?

char * uart = "/dev/ttyAMA0";
int Serial1 = serialOpen (uart, 115200); // for Arduino code compatibility reasons

then it will become
char c;
serialPutchar (Serial1 , c) ;
serialDataAvail (Serial1 ) ;
serialClose (Serial1 ) ;

a.s.o....

well, I'll try then transcoding my Arduino source... :)

Re: questions about wiringPi

Posted: Sun Nov 01, 2015 9:55 am
by davenull
except these settings described above (i.e. the patch of /boot/cmdline.txt) -

will I have to do different things before my Serial communication will work for the Raspi?
e.g., any additional UART settings on command line level?

Or will the C code then compile and work correctly for the Raspi out of the box?

Re: questions about wiringPi

Posted: Sun Nov 01, 2015 2:55 pm
by davenull
obviously, amazingly, the code seems to work... :shock:

Not extremely quick, but good for a start 8-)

share and enjoy!

for the Raspi:

Code: Select all

/*     Tx master  
 *     Raspberry Pi   
 *     ============
 *     ver 0006.2
 *     Raspbian 8.0
 */
 

// (C) Helmut Wunder (HaWe) 2015
// freie Verwendung für private Zwecke
// für kommerzielle Zwecke nur nach Genehmigung durch den Autor.
// Programming language: gcc  C/C++, Geany IDE 
// protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// http://creativecommons.org/licenses/by-nc-sa/3.0/



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>

#include "VG/openvg.h"
#include "VG/vgu.h"
#include "fontinfo.h"
#include "shapes.h"
#include "shapes_plus.h"

#include <wiringPi.h>
#include <wiringSerial.h>

#define  byte  uint8_t

char   * uart  =  "/dev/ttyAMA0";
int    Serial1;

 
//=====================================================================================
//  timer

uint32_t millisec()
{
   struct timeval now;
   uint32_t ticks;
   gettimeofday(&now, NULL);
   ticks=now.tv_sec*1000+now.tv_usec/1000;
   return(ticks);
}

#define  millis  millisec


//=====================================================================================
// openvg + shapes_plus

int _scrwidth_, _scrheight_;

#define vgHidewindow  HideWindow
#define vgShowwindow  End
#define vgcls()       ClearWindowRGB(_scrwidth_, _scrheight_, 0, 0, 0);	
#define vgStart       Start
#define vgInit        init 
#define vgCleanup     finish

int      _fontsize_ = 10;
Fontinfo _font_     = MonoTypeface;


inline void setfontsize(int size) { _fontsize_ = size; }

inline void setfonttype(Fontinfo myfont) { _font_ = myfont; }

inline void lcdprintxytop(float x, float y, char * buf) {
	Text(x, _scrheight_-y, buf, _font_ , _fontsize_); 
}

inline void lcdprintxy(float x, float y, char * buf) {
	Text(x, y, buf, _font_ , _fontsize_); 
}


void vgInitgraph() {
	vgInit(& _scrwidth_, & _scrheight_);       // Graphics initialization

    vgStart(_scrwidth_, _scrheight_);   // Start the picture
    vgcls();	
    
    Stroke(255, 255, 255, 1);  // Set these at the start, no need to    
    Fill(255,255,255, 1);      // keep calling them if colour hasn't changed
    setfonttype(MonoTypeface);    
    setfontsize(20);
}



//=====================================================================================
// debug monitor

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); 
  printf(sbuf); printf("\n");
  for(cnt=0; cnt<8; ++cnt) {
    sprintf(sbuf, "%3d ", array[cnt]);      // print on TFT
    lcdprintxy(cnt*3*8, line+10, sbuf);
    printf(sbuf); 
  }   
  printf("\n");
 
} 

//=====================================================================================
//=====================================================================================
// serial com


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


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( serialDataAvail( Serial1 ) ) { // grab new char, test for sync char, if so start adding to buffer
    buf[*cnt] = (uint8_t)serialGetchar( Serial1 );
    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++) {                     // better use write() ?
     serialPutchar( Serial1, sendbuf[i]);                // Send values to the Rx Arduino       
  }       
  //serialFlush( Serial1 );                              // clear output buffer
  
  //displayvalues(20, "Transmitted...: ", sendbuf);
  sprintf(sbuf, "%4d %4d", sendbuf[4], sendbuf[6]);
  //lcdprintxy(0, 20, sbuf);
  printf(sbuf); printf("\n");

 
  //     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
       
       
  }
 
}


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

 
int main() {
    unsigned long timesav;
    char  sbuf[128];
    char  instr[128];
     
    printf("initializing..."); printf("\n"); 
    
    // UART Serial com port 
    Serial1 = serialOpen (uart, 115200); // for Arduino code compatibility reasons 
    
    while(1) { loop(); }  
    
    serialClose( Serial1);
   
    exit(0);
}

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