This controller provides 54 On,Off and display select commands.
This number is limited by the size of the EEPROM and program memories.
The commands are grouped into 10 areas, which are selected by the UP and Down buttons. The area is identified on the top line of the display.
Each area has multiple channels, which are selected by the Left and Right buttons. Each may design an Off, an On or a display select command. The channel is identified on the bottom line of the display.
The Center button initiates a transmission. When the controller is off, pressing the Center button initiates power on.
The controller is based on the rosette, originally made to control an RV generator.
The main board contains the Picaxe 18M2+ micro-controller, a DS18B20 digital temperature sensor, the transmitter and the power control circuit. It is connected by plug-in cables to the key rosette, the battery and the display, which uses I2C.
Power is switched by the PNP transistor and maintained by the microcontroller via the NPN transistor.
It is turned off after a timed interval after the last button press.
#rem OLED_Control.bas For the Universal OLED Transmitter
This is the hand-held controller with a 2x17 blue oled character display and rosette push-buttons
John Saunders 10/16/2020 All new memory usage. 11/1/2020 Added channel to Tower Display
2020/12/4 corrected table addresses in the Master Table fot LR East and Garden
2020/12/17 Corrected Clear outlet OFF code ("J")
2021/5/24 Changed bullseye to Houses
2022/6/4 Changed houses to Missions and added Gas Sensor
#endrem
#picaxe 18M2
rem Inputs:
symbol KeyOK = pinC.2 'Keys are low when pressed
symbol KeyDown = pinC.1
symbol KeyLeft = pinC.0
symbol KeyRight = pinC.6
symbol KeyUp = pinC.7
symbol BatteryPort = B.6 'FVR=2.048V, 2:1 divider
symbol TempPort = B.7 'For DS18B20
symbol TP = B.3 'TestPoint
rem outputs:
symbol TX_Port = B.0 'Normally low
symbol KeepAlive = B.5 'High keeps power on
symbol OLEDReset = B.2 'Low resets
rem constants:
symbol NumAreas = 10 'Size of area array
symbol TX_Preamble = 20 'A long pulse before the serial transmission to trigger an interrupt
symbol TX_Ser_Setup = 10 'Gives time to execute the serial in command in the interrupt procedure
symbol IdleCountMax = 1300
symbol MasterAddr = 45
symbol ChannelShift = 210
symbol CommandShift = 380
symbol SelectorShift = 400
rem variables:
symbol OnOff = bit0 '1 is OFF, 0 is ON
symbol Row = bit1 '1 is bottom row,0 is top row
symbol ColPos = b1
symbol Scratch = b2
symbol CharData = b3
symbol DataAddr = b4 'Base address in DATA of a channel array
symbol Tens = b5
symbol Units = b6
symbol ChanIx = b7 'Index to a particular output-command combination for a receiver
symbol NumChan = b8 'Number of cbannels in a channel array
symbol Decimals = b9
symbol AreaIx = b10 'Index into the channel array
symbol CmdDisp = b11 '2 is the display mode, 3 is Command Mode
symbol StrLen = b12 'Number of bytes in a string
symbol ChanAddr = b13 ;Address in DATA of channel data
symbol TableAddr = w11 'Address in Table of the start of an channel string array
symbol TableAddrLSB = b22
symbol IdleCount = w12 'For power down on idle
symbol DecData = w13
#rem
RAM Allocation:
28-44 Display buffer
45 - 89 Area array.of NumArea areas sections. Each has 4 bytes:
byte 0 MS bit is the MS bit of TableAddr. The rest is NumChan.
byte 1 Is the LS bits of TableAddr
byte 2 MS bit is the mode: o = Control, 1 is Display, rest is string length of the upper line
byte 3 DataAddr
DATA Allocation:
0 - 223 Channel arrays. There are NumAreas number of arrays: Each has
NumChan sections each with:
byte 0 Offset to be added to TableAddr to get the bottom line string address
byte 1 Key code for either Display or Control ON
byte 2 Control only key code for off
A single string for top line of StrLen bytes
#endrem
DATA 0,(0,"1","0", 8,"3","2", 19,"5","4", 31,"7","6", 44,"L","V",54,"Gazebo")
DATA 22,(0,"m","J",12,"X","N", 21,"d","9",31,"j","T",40,"Garden")
DATA 41,(0,"R","G",12,"S","U", 19,"b","f", 30,"E","F", 42,"K","8",51,"LR West")
DATA 64,(0,"C", 12,"D", 22,"A", 28,"E", 37,"B",45,"rgb Display")
DATA 86,(0,"c", 15,"d", 27,"a", 43,"b", 56,"e",69,"f",78,"Atmosphere")
DATA 110,(0,"I","C", 12,"d","9", 16,"P","l", 29,"M","g", 37,"Y","W",47,"LR East")
DATA 133,(0,"j",8,"k", 17,"l", 25,"m", 34,"n", 40,"o",47,"Tower Display")
DATA 159,(0,"K", 4,"L", 8,"M", 19,"N", 27,"O", 40,"P",47,"Red LED Display") '
DATA 187,(0,"i","k", 9,"a","c", 15,"A","H", 23,"D","H", 33,"e","H",42,"Garage")
DATA 210,(0,"g",11,"Gas Sensor ")
DATA 254,(1,2) 'ChanIx,AreaIx
#rem
TABLE Allocation:
0-500 Botton line strings in the same sequence as in the Channel array. No nulls
#endrem
rem receiver strings:
TABLE 0,("Owl Spit","Cherub Pour","Strip Lights","String Lights","28V Output")
TABLE 58,("Clear Outlet","Clear Tip","Clear Ring","Girl Pump")
TABLE 99,("Ceiling Lamp","Speaker","Floor Light","Shelf Lights","Pineapple")
TABLE 152,("Temperatures","Humidities","Garage","Barometer","Voltages")
TABLE 198,("Ext Temperature","Ext Humidity","Room Temperature","Room Humidity","Solar Current","Barometer")
TABLE 277,("Hanging Lamp","Eggs","Circle Lights","Missions","Flashing ")
TABLE 336,("Color On","Color Off","Tower On","Tower Off","PWM On","PWM Off")
TABLE 384,("Date","Time","Temperature","Humidity","Solar Current","Battery")
TABLE 432,("Pole Lamp","Flower","Cube Red","Cube Green","Cube Blue")
TABLE 479,("Air Quality")
The method of determining memory positionsa is as follows.
The area string and the control codes are in EEPROM. This also indirectly points to the location in program memory where the command string is located.
These are loaded into RAM on program start by the TABLE keyword.
This is a 3- step procedure.
The start of the command string list for an area is set in init in the Master table. This also gives the number of commands for the area and where to find the area string.
Init:
HIGH KeepAlive
SETFREQ m4
GOSUB tempAndVolts
DO UNTIL KeyOK = 1 'View the status display while the center key is depressed
PAUSE 100
LOOP
READ 254, ChanIx, AreaIx
LET IdleCount = 0
rem field values are:1=no of fields in DATA line(*128 if display),2=address in TABLE (less 256 if Display)
rem ,3=No of chars in area,(*128 if <10),4=DATA address
rem Gazebo Garden LR West rgb Display Atmosphere LR East Tower Display Red LED Display Garage Gas Sensor
POKE MasterAddr, 5,0,$85,0, 4,58,$85,22, 5,99,$86,41, 5,152,10,64, 6,198,9,86, $85,21,$86,110, $86,80,12,133, $86,128,14,159, $85,176,$85,187,$81,223,11,210
GOSUB DispChannel
GOSUB DispArea
main:
IF KeyUp = 0 THEN
INC AreaIx
IF AreaIx >= NumAreas THEN
LET AreaIx = 0
ENDIF
LET ChanIx = 0
GOSUB DispArea
GOSUB DispChannel
DO
PAUSE 100
LOOP UNTIL KeyUp = 1
ENDIF
IF KeyDown = 0 THEN
LET IdleCount = 0
IF AreaIx > 0 THEN
DEC AreaIx
ELSE
LET AreaIx = NumAreas - 1
ENDIF
LET ChanIX = 0
GOSUB DispArea
GOSUB DispChannel
DO
PAUSE 100
LOOP UNTIL KeyDown = 1
ENDIF
rem Change channel
IF KeyRight = 0 THEN
LET IdleCount = 0
IF OnOff = 0 OR CmdDisp = 2 THEN
INC ChanIx
IF ChanIx >= NumChan THEN
LET ChanIx = 0
ENDIF
LET OnOff = 1
ELSE
LET OnOff = 0
ENDIF
GOSUB DispChannel
DO
PAUSE 100
LOOP UNTIL KeyRight = 1
ENDIF
IF KeyLeft = 0 THEN
LET IdleCount = 0
LET IdleCount = 0
IF OnOFF = 1 OR CmdDisp = 2 THEN
IF ChanIx > 0 THEN
DEC ChanIx
ELSE
LET ChanIx = NumChan - 1
ENDIF
LET OnOff = 0
ELSE
LET OnOff = 1
ENDIF
GOSUB DispChannel
DO
PAUSE 100
LOOP UNTIL KeyLeft = 1
ENDIF
IF KeyOK = 0 THEN 'Transmit a command
LET IdleCount = 0
POKE 44,CharData
GOSUB WriteOLED
HIGH TX_Port 'This pulse unlocks the receiver
PAUSE TX_Preamble
LOW TX_Port
PAUSE TX_Ser_Setup
IF CmdDisp = 3 THEN 'Command
LET Scratch = ChanAddr + 2 - OnOff
READ Scratch,CharData
SEROUT TX_Port,N2400_4,("14L1776",CharData,13,10) 'The CR,LF is for debugging
ELSE 'Display
LET Scratch = ChanAddr + 1
READ Scratch,CharData
SEROUT TX_Port,N2400_4,("14L1776O,",CharData,13,10)
ENDIF
HI2COUT 0,($CF)
HI2COUT $40,(CharData)
DO
PAUSE 100
LOOP UNTIL KeyOK = 1
ENDIF
PAUSE 100
INC IdleCount
IF IdleCount < IdleCountMax THEN main 'Exit on no activity
Write 254,ChanIx,AreaIx
LOW KeepAlive
END
tempAndVolts:
ReadTemp12 TempPort,DecData
GOSUB InitDisp
LET DecData = DecData + 880 **7373 -67 'Fahrenheit (32F to 257F)
HI2COUT 0,($80) 'Start of first row
LET Decimals = 0
GOSUB WriteDec 'Temperature
HI2COUT $40,($80,"F")
FVRSETUP FVR2048
ADCCONFIG 3
READADC10 BatteryPort,DecData
LET DecData = DecData * 2 / 5
HI2COUT 0,($89) 'Column 9
LET Decimals = 2
GOSUB WriteDec 'Volts
HI2COUT $40,("V")
RETURN
InitDisp: 'From the TABLEsheet
HIGH OLEDReset
HI2CSETUP I2CMASTER,$78,i2cfast,i2cbyte 'The OLED Display
PAUSE 100
HI2COUT (0,0x2A); //function set (extended command set)
HI2COUT (0,0x71); //function selection A
HI2COUT ($40,0x0); // TABLE(0x5C) = disable regulator (5V I/O)
HI2COUT (0,0x28); //function set (fundamental command set)
HI2COUT (0,0x08); //display off, cursor off, blink off
HI2COUT (0,0x2A); //function set (extended command set)
HI2COUT (0,0x79); //OLED command set enabled
HI2COUT (0,0xD5); //set display clock divide ratio/oscillator frequency
HI2COUT (0,0x70); //set display clock divide ratio/oscillator frequency
HI2COUT (0,0x78); //OLED command set disabled
HI2COUT (0,0x08); //extended function set (2-lines)
HI2COUT (0,0x06); //COM SEG direction
HI2COUT (0,0x72); //function selection B
HI2COUT ($40,0x00); //ROM CGRAM selection A
HI2COUT (0,0x2A); //function set (extended command set)
HI2COUT (0,0x79); //OLED command set enabled
HI2COUT (0,0xDA); //set SEG pins hardware configuration
HI2COUT (0,0x00); //set SEG pins hardware configuration
HI2COUT (0,0xDC); //function selection C
HI2COUT (0,0x00); //function selection C
HI2COUT (0,0x81); //set contrast control
HI2COUT (0,0x7F); //set contrast control
HI2COUT (0,0xD9); //set phase length
HI2COUT (0,0xF1); //set phase length
HI2COUT (0,0xDB); //set VCOMH deselect level
HI2COUT (0,0x40); //set VCOMH deselect level
HI2COUT (0,0x78); //OLED command set disabled
HI2COUT (0,0x28); //function set (fundamental command set)
HI2COUT (0,0x01); //clear display
HI2COUT (0,0x80); //set DDRAM address to 0x00
HI2COUT (0,0x0C); //display ON
RETURN
WriteDec:
LET Units = DecData //10 + "0"
LET Tens = DecData /10 //10 + "0"
LET DecData = DecData /100 //10
IF DecData = 0 THEN
LET DecData = " "
ELSE
LET DecData = DecData + "0"
ENDIF
SELECT Decimals
CASE 1
HI2COUT $40,(DecData,Tens,".",Units)
CASE 2
HI2COUT $40,(DecData,".",Tens,Units)
ELSE
HI2COUT $40,(" ",DecData,Tens,Units)
ENDSELECT
RETURN
GetData:
POKE 28," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
rem Input is AreaIx and ChanIx,
rem Output is NumChan,DataAddr,ChanAddr,TableAddr,CmdDisp,StrLen
LET Scratch = AreaIx * 4 + MasterAddr 'Channel entry address
PEEK Scratch,NumChan,TableAddrLSB,CharData,DataAddr
IF CharData > 127 THEN
LET CmdDisp = 3
ELSE
LET CmdDisp = 2
ENDIF
LET StrLen = CharData & $7F
LET ChanAddr = CmdDisp * ChanIx + DataAddr
READ ChanAddr,CharData 'TableAddr offset
LET TableAddr = TableAddrLSB + CharData
IF NumChan > 127 THEN
LET TableAddr = TableAddr + 256
ENDIF
LET NumChan = NumChan & $7F
RETURN
DispArea:
GOSUB GetData
'SERTXD ("AreaIx=",#AreaIx,",CmdDisp=",#CmdDisp,",DataAddr=",#DataAddr,",Strlen=",#Strlen,13,10)
LET Tens = NumChan * CmdDisp + DataAddr + 1
LET CharData = 16 - Strlen
LET ColPos = CharData / 2 + 28
FOR Units = 0 TO Strlen
LET Scratch = Tens + Units
READ Scratch,CharData
LET bptr = ColPos + Units
IF bptr < 28 OR bptr > 44 THEN
SERTXD ("invalid area bptr=",#bptr,13,10)
LET bptr=40
exit
ENDIF
POKE bptr,CharData
NEXT
LET Row = 0
GOSUB WriteOLED
LOW TP
RETURN
DispChannel:
GOSUB GetData
'SERTXD ("ChanIx=",#ChanIx,",NumChan=",#NumChan,",TableAddr=",#TableAddr,",ChanAddr=",#ChanAddr,13,10)
READ ChanAddr,CharData
LET Scratch = ChanAddr + CmdDisp
READ Scratch,Tens
LET Tens = Tens - CharData - 1
FOR Units = 0 TO Tens
READTABLE TableAddr,CharData
LET bptr = 28 + Units
IF bptr < 28 OR bptr > 44 THEN
SERTXD ("invalid channel bptr=",#bptr,13,10)
exit
ENDIF
POKE bptr,CharData
INC TableAddr
NEXT
INC bptr
IF OnOff = 0 AND CmdDisp = 3 THEN
POKE bptr," ","O","F","F"
ENDIF
IF OnOff = 1 AND CmdDisp = 3 THEN
POKE bptr," ","O","N"
ENDIF
LET Row = 1
GOSUB WriteOLED
LOW TP
RETURN
WriteOLED:
LET Scratch = Row * $40 + $80
HI2COUT 0,(Scratch)
LET bptr = 28
HI2COUT $40,(@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr)
RETURN