Raspberry BASIC > ScriptBasic

WPI - WiringPi and Sensor Interface Extension Module

(1/1)

John Spikowski:
The following is the current statues of the WPI extension module code. I have attached a pre-compiled extension module and include file compiled on the Raspberry Pi 3 B.

wpi.bas

--- Code: Script BASIC ---' WiringPi & Device Interface Extension Module - JRS 2019-06-01 MODULE WPI  ' WiringPi API FunctionsDECLARE SUB ::wiringPiSetup                ALIAS "sb_wiringPiSetup"                LIB "wpi"DECLARE SUB ::wiringPiSetupSys             ALIAS "sb_wiringPiSetupSys"             LIB "wpi"DECLARE SUB ::wiringPiSetupGpio            ALIAS "sb_wiringPiSetupGpio"            LIB "wpi"DECLARE SUB ::wiringPiSetupPhys            ALIAS "sb_wiringPiSetupPhys"            LIB "wpi"DECLARE SUB ::pinModeAlt                   ALIAS "sb_pinModeAlt"                   LIB "wpi"DECLARE SUB ::pinMode                      ALIAS "sb_pinMode"                      LIB "wpi"DECLARE SUB ::pullUpDnControl              ALIAS "sb_pullUpDnControl"              LIB "wpi"DECLARE SUB ::digitalRead                  ALIAS "sb_digitalRead"                  LIB "wpi"DECLARE SUB ::digitalWrite                 ALIAS "sb_digitalWrite"                 LIB "wpi"DECLARE SUB ::digitalRead8                 ALIAS "sb_digitalRead8"                 LIB "wpi"DECLARE SUB ::digitalWrite8                ALIAS "sb_digitalWrite8"                LIB "wpi"DECLARE SUB ::pwmWrite                     ALIAS "sb_pwmWrite"                     LIB "wpi"DECLARE SUB ::analogRead                   ALIAS "sb_analogRead"                   LIB "wpi"DECLARE SUB ::analogWrite                  ALIAS "sb_analogWrite"                  LIB "wpi"DECLARE SUB ::piGpioLayout                 ALIAS "sb_piGpioLayout"                 LIB "wpi"DECLARE SUB ::wpiPinToGpio                 ALIAS "sb_wpiPinToGpio"                 LIB "wpi"DECLARE SUB ::setPadDrive                  ALIAS "sb_setPadDrive"                  LIB "wpi"DECLARE SUB ::getAlt                       ALIAS "sb_getAlt"                       LIB "wpi"DECLARE SUB ::pwmToneWrite                 ALIAS "sb_pwmToneWrite"                 LIB "wpi"DECLARE SUB ::pwmSetMode                   ALIAS "sb_pwmSetMode"                   LIB "wpi"DECLARE SUB ::pwmSetRange                  ALIAS "sb_pwmSetRange"                  LIB "wpi"DECLARE SUB ::pwmSetClock                  ALIAS "sb_pwmSetClock"                  LIB "wpi"DECLARE SUB ::gpioClockSet                 ALIAS "sb_gpioClockSet"                 LIB "wpi"DECLARE SUB ::digitalReadByte              ALIAS "sb_digitalReadByte"              LIB "wpi"DECLARE SUB ::digitalReadByte2             ALIAS "sb_digitalReadByte2"             LIB "wpi"DECLARE SUB ::digitalWriteByte             ALIAS "sb_digitalWriteByte"             LIB "wpi"DECLARE SUB ::digitalWriteByte2            ALIAS "sb_digitalWriteByte2"            LIB "wpi"DECLARE SUB ::waitForInterrupt             ALIAS "sb_waitForInterrupt"             LIB "wpi"DECLARE SUB ::piHiPri                      ALIAS "sb_piHiPri"                      LIB "wpi"' Utility FunctionsDECLARE SUB ::msSleep                      ALIAS "sb_msSleep"                      LIB "wpi"DECLARE SUB ::delay                        ALIAS "sb_delay"                        LIB "wpi"DECLARE SUB ::delayMicroseconds            ALIAS "sb_delayMicroseconds"            LIB "wpi"DECLARE SUB ::BitStreamRead                ALIAS "sb_BitStreamRead"                LIB "wpi"DECLARE SUB ::bin2int                      ALIAS "sb_bin2int"                      LIB "wpi"' Simplified I2C access routinesDECLARE SUB ::wiringPiI2CRead              ALIAS "sb_wiringPiI2CRead"              LIB "wpi"DECLARE SUB ::wiringPiI2CReadReg8          ALIAS "sb_wiringPiI2CReadReg8"          LIB "wpi"DECLARE SUB ::wiringPiI2CReadReg16         ALIAS "sb_wiringPiI2CReadReg16"         LIB "wpi"DECLARE SUB ::wiringPiI2CWrite             ALIAS "sb_wiringPiI2CWrite"             LIB "wpi"DECLARE SUB ::wiringPiI2CWriteReg8         ALIAS "sb_wiringPiI2CWriteReg8"         LIB "wpi"DECLARE SUB ::wiringPiI2CWriteReg16        ALIAS "sb_wiringPiI2CWriteReg16"        LIB "wpi"DECLARE SUB ::wiringPiI2CSetupInterface    ALIAS "sb_wiringPiI2CSetupInterface"    LIB "wpi"DECLARE SUB ::wiringPiI2CSetup             ALIAS "sb_wiringPiI2CSetup"             LIB "wpi"' Shift LibraryDECLARE SUB ::shiftIn                      ALIAS "sb_shiftIn"                      LIB "wpi"DECLARE SUB ::shiftOut                     ALIAS "sb_shiftOut"                     LIB "wpi"' SPI LibraryDECLARE SUB ::wiringPiSPIGetFd             ALIAS "sb_wiringPiSPIGetFd"             LIB "wpi"DECLARE SUB ::wiringPiSPIDataRW            ALIAS "sb_wiringPiSPIDataRW"            LIB "wpi"DECLARE SUB ::wiringPiSPISetupMode         ALIAS "sb_wiringPiSPISetupMode"         LIB "wpi"DECLARE SUB ::wiringPiSPISetup             ALIAS "sb_wiringPiSPISetup"             LIB "wpi"   ' Native Device Interfaces  FUNCTION DHT11(pin, humidity, temperature)  WPI::wiringPiSetup()  valid = 0  retries = 0  WHILE valid = 0    bits = ""    WPI::pinMode(pin, 1)    WPI::digitalWrite(pin, 0)    WPI::delay(18)    WPI::digitalWrite(pin, 1)    WPI::delayMicroseconds(40)    WPI::pinMode(pin, 0)    bits = WPI::BitStreamRead(pin)    SPLITA bits BY "" TO samples     ' **** Extract the pulse lengths ****                                                  pulseSize = 0    last = 0    FOR index = 0 TO ubound(samples)      IF samples[index] = 1 THEN        IF last = 0 THEN          pulseSize += 1        END IF        IF pulseSize <= 40 THEN          pulses[pulseSize-1] += 1        END IF      END IF      last = samples[index]    NEXT    undef samples     ' **** Determine minimum and maximum pulse sizes, and mid-way between ****     minimum = pulses[0]    maximum = pulses[0]     FOR index = 0 TO 40      IF pulses[index] < minimum THEN minimum = pulses[index]      IF pulses[index] > maximum THEN maximum = pulses[index]    NEXT    middle = ((maximum - minimum) \ 2) + minimum     ' **** Determine outbits values ****     outbits = ""    FOR index = 0 TO 40      IF pulses[index] > middle THEN        outbits &= 1      ELSE        outbits &= 0      END IF    NEXT    UNDEF pulses     ' **** Form the bytes ****     index = 0    FOR idx = 2 TO LEN(outbits) STEP 8      byte[index] = WPI::bin2int(mid(outbits,idx,8))      index += 1    NEXT     outbits = ""      ' **** Return results ****     IF byte[0] + byte[1] + byte[2] + byte[3] = byte[4] THEN      humidity = byte[0] & "." & byte[1]      temperature = byte[2] & "." & byte[3]      GOTO Done    ELSE      retries += 1    END IF    UNDEF byte    WPI::delay(1550)  WEND  Done:  DHT11 = retriesEND FUNCTION  FUNCTION DS18B20(slave)  LOCAL temp_raw, pos  OPEN slave FOR INPUT AS #1  LINE INPUT #1, temp_raw  IF RIGHT(CHOMP(temp_raw),3) = "YES" THEN    msSleep(200)    LINE INPUT #1, temp_raw    temp_raw = CHOMP(temp_raw)    pos = INSTR(temp_raw,"t=")    DS18B20 = MID(temp_raw, pos + 2) / 1000  ELSE    DS18B20 = "<Sensor Error>"  END IF  CLOSE (1)END FUNCTION  ' Helper Functions function shifts(v,p,ar)  local bp,ba,co,cq,bi,x,y,d  bp=1  x=0xffffffff and v  for co=0 to 31    ba[co]=0  next  for co=0 to 31    bi=x and bp    cq=co+p    if (bi<>0) then      if ((cq>=0)and(cq<32)) then        ba[cq]=1      end if    end if    bp = bp + bp  next  bp=1  y=0  '  ' SUPPORT FOR ARITHMETIC RIGHT SHIFTS  '  d=100  if (ar) then    if (x and 0x80000000) then       d=31+p    end if  end if  '  for co=0 to 31   if ((ba[co]<>0)or(co>=d)) then      y=y or bp    end if    bp = bp + bp  next  shifts=yend function  ' PRINT shifts(0x80000000,2),"\n"' PRINT shifts(-32,-2,1),"\n"' PRINT shifts(8,-2),"\n"  END MODULE 
interface.c

--- Code: C ---/*WiringPi Extension ModuleUXLIBS: -lc -lwiringPi*/  #include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <string.h>#include <time.h>#include <unistd.h>#include <fcntl.h>#include "../../basext.h"#include <wiringPi.h>#include <wiringPiI2C.h>#include <wiringShift.h>#include <wiringPiSPI.h> #define MAXTIMINGS  85   /************************** Extension Module Functions**************************/ typedef struct _ModuleObject {  void *HandleArray;}ModuleObject,*pModuleObject;  besVERSION_NEGOTIATE  return (int)INTERFACE_VERSION;besEND  besSUB_START  pModuleObject p;   besMODULEPOINTER = besALLOC(sizeof(ModuleObject));  if( besMODULEPOINTER == NULL )return 0;   p = (pModuleObject)besMODULEPOINTER;  return 0;besEND  besSUB_FINISH  pModuleObject p;   p = (pModuleObject)besMODULEPOINTER;  if( p == NULL )return 0;  return 0;besEND   /****************** WiringPi Functions******************/ // Core wiringPi functions  besFUNCTION(sb_wiringPiSetup)  int status;  status = wiringPiSetup();  besRETURN_LONG(status);besEND  besFUNCTION(sb_wiringPiSetupSys)  int status;  status = wiringPiSetupSys();  besRETURN_LONG(status);besEND  besFUNCTION(sb_wiringPiSetupGpio)  int status;  status = wiringPiSetupGpio();  besRETURN_LONG(status);besEND  besFUNCTION(sb_wiringPiSetupPhys)  int status;  status = wiringPiSetupPhys();  besRETURN_LONG(status);besEND  besFUNCTION(sb_pinModeAlt)  VARIABLE Argument;  int pin, mode;  besARGUMENTS("ii")    &pin, &mode  besARGEND  pinModeAlt(pin,mode);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_pinMode)  VARIABLE Argument;  int pin, mode;  besARGUMENTS("ii")    &pin, &mode  besARGEND  pinMode(pin,mode);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_pullUpDnControl)  VARIABLE Argument;  int pin, pud;  besARGUMENTS("ii")    &pin, &pud  besARGEND  pullUpDnControl(pin,pud);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_digitalRead)  int pin, rtn;  besARGUMENTS("i")    &pin  besARGEND  rtn = digitalRead(pin);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_digitalWrite)  VARIABLE Argument;  int pin, value;  besARGUMENTS("ii")    &pin, &value  besARGEND  digitalWrite(pin,value);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_digitalRead8)  int pin;  unsigned int rtn;  besARGUMENTS("i")    &pin  besARGEND  rtn = digitalRead8(pin);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_digitalWrite8)  VARIABLE Argument;  int pin, value;  besARGUMENTS("ii")    &pin, &value  besARGEND  digitalWrite8(pin,value);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_pwmWrite)  VARIABLE Argument;  int pin, value;  besARGUMENTS("ii")    &pin, &value  besARGEND  pwmWrite(pin,value);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_analogRead)  int pin, rtn;  besARGUMENTS("i")    &pin  besARGEND  rtn = analogRead(pin);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_analogWrite)  VARIABLE Argument;  int pin, value;  besARGUMENTS("ii")    &pin, &value  besARGEND  analogWrite(pin,value);  besRETURNVALUE = NULL;besEND  // On-Board Raspberry Pi hardware specific  besFUNCTION(sb_piGpioLayout)  int rtn;  rtn = piGpioLayout();  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wpiPinToGpio)  int wpiPin, rtn;  besARGUMENTS("i")    &wpiPin  besARGEND  rtn = wpiPinToGpio(wpiPin);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_physPinToGpio)  int physPin, rtn;  besARGUMENTS("i")    &physPin  besARGEND  rtn = physPinToGpio(physPin);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_setPadDrive)  VARIABLE Argument;  int group, value;  besARGUMENTS("ii")    &group, &value  besARGEND  setPadDrive(group,value);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_getAlt)  int pin, rtn;  besARGUMENTS("i")    &pin  besARGEND  rtn = getAlt(pin);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_pwmToneWrite)  VARIABLE Argument;  int pin, freq;  besARGUMENTS("ii")    &pin, &freq  besARGEND  pwmToneWrite(pin,freq);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_pwmSetMode)  VARIABLE Argument;  int mode;  besARGUMENTS("i")    &mode  besARGEND  pwmSetMode(mode);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_pwmSetRange)  VARIABLE Argument;  unsigned int range;  besARGUMENTS("i")    &range  besARGEND  pwmSetRange(range);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_pwmSetClock)  VARIABLE Argument;  unsigned int divisor;  besARGUMENTS("i")    &divisor  besARGEND  pwmSetClock(divisor);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_gpioClockSet)  VARIABLE Argument;  int pin, freq;  besARGUMENTS("ii")    &pin, &freq  besARGEND  gpioClockSet(pin,freq);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_digitalReadByte)  unsigned int rtn;  rtn = digitalReadByte();  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_digitalReadByte2)  unsigned int rtn;  rtn = digitalReadByte2();  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_digitalWriteByte)  VARIABLE Argument;  int value;  besARGUMENTS("i")    &value  besARGEND  digitalWriteByte(value);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_digitalWriteByte2)  VARIABLE Argument;  int value;  besARGUMENTS("i")    &value  besARGEND  digitalWriteByte2(value);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_waitForInterrupt)  int pin, ms, rtn;  besARGUMENTS("ii")    &pin, &ms  besARGEND  rtn = waitForInterrupt(pin,ms);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_piHiPri)  const int pri;  int rtn;  besARGUMENTS("i")    &pri  besARGEND  rtn = piHiPri(pri);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_BitStreamRead)  char buf[850];  int pin, status, idx;  besARGUMENTS("i")    &pin  besARGEND  for (idx = 0; idx < 850; idx++){    status = digitalRead(pin);    delayMicroseconds(5);    if (status == 0){      buf[idx] = 0x30;    }else{      buf[idx] = 0x31;    }  }  besRETURN_STRING(buf);besEND   // Simplified I2C access routines  besFUNCTION(sb_wiringPiI2CRead)  int fd,rtn;  VARIABLE Argument;  besARGUMENTS("i")    &fd  besARGEND  rtn = wiringPiI2CRead(fd);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiI2CReadReg8)  int fd,reg,rtn;  VARIABLE Argument;  besARGUMENTS("ii")    &fd,&reg  besARGEND  rtn = wiringPiI2CReadReg8(fd,reg);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiI2CReadReg16)  int fd,reg,rtn;  VARIABLE Argument;  besARGUMENTS("ii")    &fd,&reg  besARGEND  rtn = wiringPiI2CReadReg16(fd,reg);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiI2CWrite)  int fd,data,rtn;  VARIABLE Argument;  besARGUMENTS("ii")    &fd,&data  besARGEND  rtn = wiringPiI2CWrite(fd,data);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiI2CWriteReg8)  int fd,reg,data,rtn;  VARIABLE Argument;  besARGUMENTS("iii")    &fd,&reg,&data  besARGEND  rtn = wiringPiI2CWriteReg8(fd,reg,data);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiI2CWriteReg16)  int fd,reg,data,rtn;  VARIABLE Argument;  besARGUMENTS("iii")    &fd,&reg,&data  besARGEND  rtn = wiringPiI2CWriteReg16(fd,reg,data);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiI2CSetupInterface)  const char *device;  int devId,rtn;  VARIABLE Argument;  besARGUMENTS("zi")    &device,&devId  besARGEND  rtn = wiringPiI2CSetupInterface(device,devId);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiI2CSetup)  const int devId;  int rtn;  VARIABLE Argument;  besARGUMENTS("i")    &devId  besARGEND  rtn = wiringPiI2CSetup(devId);  besRETURN_LONG(rtn);besEND   // Shift Library  besFUNCTION(sb_shiftIn)  VARIABLE Argument;  uint8_t dPin,cPin,order,rtn;  besARGUMENTS("iii")    &dPin,&cPin,&order  besARGEND  rtn = shiftIn(dPin,cPin,order);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_shiftOut)  VARIABLE Argument;  uint8_t dPin,cPin,order,val;  besARGUMENTS("iiii")    &dPin,&cPin,&order,&val  besARGEND  shiftOut(dPin,cPin,order,val);  besRETURNVALUE = NULL;besEND   // SPI Library  besFUNCTION(sb_wiringPiSPIGetFd)  int channel,rtn;  VARIABLE Argument;  besARGUMENTS("i")    &channel  besARGEND  rtn = wiringPiSPIGetFd(channel);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiSPIDataRW)  int channel,len,rtn;  unsigned char *data;  VARIABLE Argument;  besARGUMENTS("izi")    &channel,&data,&len  besARGEND  rtn = wiringPiSPIDataRW(channel,data,len);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiSPISetupMode)  int channel,speed,mode,rtn;  VARIABLE Argument;  besARGUMENTS("iii")    &channel,&speed,&mode  besARGEND  rtn = wiringPiSPISetupMode(channel,speed,mode);  besRETURN_LONG(rtn);besEND  besFUNCTION(sb_wiringPiSPISetup)  int channel,speed,rtn;  VARIABLE Argument;  besARGUMENTS("ii")    &channel,&speed  besARGEND  rtn = wiringPiSPISetup(channel,speed);  besRETURN_LONG(rtn);besEND   /***************** Utility Functions*****************/ besFUNCTION(sb_msSleep)  //DIM AS int msval, t;  long t;  besARGUMENTS("i")    &t  besARGEND  usleep(t);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_delay)  unsigned int howLong;  besARGUMENTS("i")    &howLong  besARGEND  delay(howLong);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_delayMicroseconds)  unsigned int howLong;  besARGUMENTS("i")    &howLong  besARGEND  delayMicroseconds(howLong);  besRETURNVALUE = NULL;besEND  besFUNCTION(sb_bin2int)  const char* s;  besARGUMENTS("z")    &s  besARGEND  register unsigned char *p = s;  register unsigned int   r = 0;  while (p && *p ) {    r <<= 1;    r += (unsigned int)((*p++) & 0x01);  }  besRETURN_LONG(r);besEND 

John Spikowski:
I have updated the first post with new source and binary attachment. The following enhancements / changes have been made in this release.

BitStreamRead function reads the pin at the C level and returns the sampled bits as a 850 byte string. This will be enhanced in the next release to be able to define the buffer size, delay between pin reads and optionally return the binary string pre-parsed and checksum verified.

bin2int takes a string of bits and returns an integer.

DHT11 This device function has been added to the wpi.bas include file and the dedicated C version removed. The plan is to do device / sensor interfaces in native ScriptBasic and add what needed C routines to the WPI extension modules that makes sense.

Navigation

[0] Message Index

Go to full version