' WiringPi & Device Interface Extension Module - JRS 2019-06-01
MODULE WPI
' WiringPi API Functions
DECLARE 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 Functions
DECLARE 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 routines
DECLARE 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 Library
DECLARE SUB ::shiftIn ALIAS "sb_shiftIn" LIB "wpi"
DECLARE SUB ::shiftOut ALIAS "sb_shiftOut" LIB "wpi"
' SPI Library
DECLARE 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 = retries
END 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=y
end function
' PRINT shifts(0x80000000,2),"\n"
' PRINT shifts(-32,-2,1),"\n"
' PRINT shifts(8,-2),"\n"
END MODULE