OLED Portable Display OLED Basic Version

OLED Portable Display Picaxe Basic Declarations

#rem OLED Portable Display.bas 

This is a hand-held OLED display receiving data from the 

Mobile Logger, the Solar Transmitter.and the Alpha LED Clock

John Saunders

10/11/2018, 1/14/2018 changed line 305 because of negative altitude

#endrem

#picaxe 14M2


rem Connections

symbol DispRst            = B.1

symbol ButtonLeft      = pinB.2

symbol ButtonRight     = pinB.5

symbol Rcvr_In         = C.0

symbol VoltPort           = C.4

symbol TP             = C.1

symbol Int_Port           = pinC.2


rem Dedicated I2C pins: SCL = b.3, SDA = B.4


rem Interrupt only variables

symbol        Msg_Start     = b1

symbol        Plen        = b2

symbol    Key_Code     = b3

symbol    ChckHex     = b4

symbol    ChckSum      = b5

symbol    Msg_End         = b6

symbol     I_tmp         = b7

symbol    MsgLoc     = b8



#rem Global variables

Pages:0=Battery Volts,1=Alitude&Logger Volts,2=Logger temperature&humidity

3=Outside Solar Current and battery volts,4= outside temperature&humidity

5=Time&Date

#endrem

symbol    Page         = b10        


rem flags

symbol    Pressed     = bit0

symbol    NewData     = bit1

symbol    ButtonEvent     = bit2

symbol    Row         = bit3        '0 = top, 1 = bottom


    

rem Pointer Vatiables

symbol    DataAddr        = b14

symbol    ConfigAddr     = b15

symbol    MemAddr     = b16

symbol    TableAddr     = b17      


rem Local Variables

symbol    Loop_Count    = b19

symbol    Scratch     = b20

symbol    DecData     = b21

symbol    Indx         = b22        'Used for iteration in top-level subroutines

symbol    Iter         = b23        'Used for iteration in subroutines called from loops

symbol    Limit         = b24

symbol    Column     = b25

symbol    BattVolt     = w13


rem constants

symbol  MsgBase        = 210


rem Fixed strings which will be partly overwritten by values

TABLE    0,("Batt V Gate Door")         'Row 0, Page 0

TABLE   16,("0.00 V          ")         'Row 1, Page 0 

TABLE   32,("Alt&Logger Volts")        'Row 0, Page 1      

TABLE   48,("00000  00.00V   ")        'Row 1, Page 1

TABLE   64,("Logger Temp&Hum ")        'Row 0, Page 2                

TABLE   80,("000.0",$80,"F  000%   ")    'Row 1, Page 2

TABLE   96,("Solar Curr&Bat V")        'Row 0, Page 3

TABLE  112,("000 MA 000 V    ")        ;Row 1, Page 3

TABLE  128,("Outside Temp&Hum")           'Row 0, Page 4 

TABLE  144,("000",$80,"F 000%      ")     'Row 1, Page 4            

TABLE  160,("Master Time&Date")        'Row 0, Page 5               

TABLE  176,("HH:MM MO/DD     ")        'Row 1, Page 5            


#rem Memory Map (28 - 255 total) MSB first, all in ASCII

: 28,  

30= Battery Volts ("0.00")

34= Altitude ("00000", 2nd may be "-"),49 Logger supply volts ("00.00")

39= Logger Temperature ("000.0"), 44= Logger Humidity ("000")

60= Solar Current ("000"),63=Solar Battery Voltage ("0.00")

54= Outside temperature("000"),57=Outside Humidity ("000")

67= Date("00/00"), 72=Time("00:00")


80= Gate("    " or "OPEN" or "SHUT")  Used on Row 1 of Page 0 

84= Garage Door ("    " or "DOWN" or "UP  ") Used on Row 1 of Page 0

these 2 also in positions 14 & 15 of pages 1-5 as " ","O","S", "D", "U"


Received messages: 210 - 238 (ASCII, no decimal points (MS first),         


rem Variable coonfiguration tables. Indexed by Page (Page 0 is separate)

rem Each entry has three numbers for each of 2 variables.

The first is the memory address ddress, the second the number of characters, the third is the column of the MSB

#endrem


DATA   0,(30,4,0,80,9,7)        'Page 0 lower variables

DATA   6,(34,5,0,48,5,7)        'Page 1 lower variables

DATA  12,(39,5,0,44,3,9)        'Page 2 lower variables

DATA  18,(60,3,0,63,4,7)        'Page 3 lower variables

DATA  24,(54,3,0,57,3,6)        'Page 4 lower variables

DATA  30,(72,5,0,67,5,6)        'Page 5 lower variables

OLED Portable Display Picaxe Init and Main

rem ------------------------------------ Execution Code --------------------------------------


Init:

SETFREQ m8

HI2CSETUP I2CMASTER,$78,i2cfast,i2cbyte            'The OLED Display

GOSUB InitDisp

FOR Scratch = 28 TO 76

    POKE Scratch, "0"

NEXT

FOR Scratch = 80 TO 88

    POKE Scratch, " "

NEXT

LOW TP

LET Page = 1                            'Altitude 11/6/2018

LET Loop_Count = 0

GOSUB Refresh


Main:


IF ButtonLeft = 0 THEN

    IF Page > 0 THEN

        DEC Page

    ELSE

        LET Page = 5

    ENDIF

    LET ButtonEvent = 1

ENDIF

 

IF  ButtonRight = 0 THEN

    IF Page < 5 THEN

        INC Page

    ELSE

        LET Page = 0

    ENDIF

    LET ButtonEvent = 1

ENDIF


IF ButtonEvent = 1 THEN

    SETINT OFF

    GOSUB Refresh            'The background     

    GOSUB Update            'The variable content

    DO WHILE  ButtonLeft = 0 OR ButtonRight = 0

         PAUSE 10

    LOOP

    LET ButtonEvent = 0

    SETINT %00000100,%00000100    'Interrupt when Int_Port high. 

ELSEIF Page = 0 THEN

    GOSUB GetVolts

ELSE

    PAUSE 10

ENDIF

GOTO Main

OLED Portable Display Picaxe Sub-Programs

rem ------------------------------------ Top level subroutines --------------------------------------

InitDisp:                                        'From the display datasheet 

PAUSE 100

HI2COUT (0,0x2A);  //function set (extended command set)  

HI2COUT (0,0x71);  //function selection A  

HI2COUT ($40,0x5C);  // data(0x5C) = enable 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


GetVolts:

rem Measure and store Battery voltage

FVRSETUP FVR4096

ADCCONFIG %011

READADC10 VoltPort,BattVolt

LET BattVolt =  4 * BattVolt + 5 / 10

LET BattVolt = BattVolt // 1000

LET Scratch = BattVolt/100 + "0"

POKE 30,Scratch

POKE 31,"."

LET BattVolt = BattVolt // 100

LET Scratch = BattVolt / 10    + "0"

POKE 32,Scratch

LET Scratch    = BattVolt // 10 + "0"

POKE 33,Scratch

RETURN


Refresh:            'Writes the fixed strings to the buffers when the Page changes

FOR Row = 0 TO 1

    LET DecData = Row * $40 + $80

    HI2COUT 0,(DecData)

    LET Scratch = 2 * Page + Row 

    LET DecData = 16 * Scratch    

    FOR Indx = 0 TO 15

        LET TableAddr = DecData + Indx

        READTABLE TableAddr,Scratch

        Hi2COUT $40,(Scratch)

    NEXT

NEXT

RETURN


Update:                        'Writes the numerical information to the display

FOR Indx = 0 TO 1                    'Two vatiables per page lower row        '

    LET Scratch = 6*Page            'The configuration table entry for the page variables

    LET ConfigAddr = 3 * Indx + Scratch

    READ ConfigAddr,DecData,Limit, Column

    LET Scratch = $C0 + Column

    HI2COUT 0,(Scratch)            'Set cursor to MSD columb        

    FOR Iter = 1 TO Limit

        LET MemAddr = DecData + Iter - 1

        PEEK MemAddr, Scratch            

        Hi2COUT $40,(Scratch)

    NEXT

NEXT

rem Put event markers at the end 2 columns of the lower line except for Page 0

IF Page <> 0 THEN

    HI2COUT 0,($CE)

    PEEK 80,Scratch

    Hi2COUT $40,(Scratch)

    PEEK 84,Scratch

    Hi2COUT $40,(Scratch)

ENDIF

RETURN


Interrupt:

LET bptr=MsgBase

LET Key_Code = "Z"

rem First gate is to reject short bursts

LET Plen =0

DO  WHILE Int_Port = 1        'Noise interrupts are nearly always shorter

    INC Plen

LOOP 

IF Plen < 10 OR Plen > 20 THEN End_Interrupt     'Minimises the time to recover from a noise interrupt

FOR I_tmp = 0 TO 5

    IF Int_Port = 1 THEN

        SERTXD ("Positive pulse=",#plen,",Low = ",#I_tmp,13,10)

        GOTO End_Interrupt

    ENDIF

NEXT

rem Second gate is to use a 7-character SERIN unlock code, min timeout is 60 ms

HIGH TP

rem Input commands and message with length character, checksum and up t0 21 data characters, including included, but not enclosed,commas

SERIN [40,timeout],Rcvr_In,N2400_8,("14L1776"),Key_Code,I_tmp,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr

LOW TP

rem No timeout: Must be a Message

PEEK MsgBase, I_tmp               'The length code, 60 + number of data bytes between commas, including commas between fields

LET Msg_End = MsgBase - 59  + I_Tmp         'Address of last data character

LET Msg_Start = MsgBase + 2

rem Calculate the checksum of the received message

LET Chcksum = 0

FOR MsgLoc = Msg_Start TO Msg_End    'Sum of message bytes not including bracketing commas

    PEEK MsgLoc,ChckHex 

    LET ChckSum = ChckSum + ChckHex

NEXT

rem Compare the calculated with the 2 received checksum characters, one at a time

LET ChckHex = ChckSum / 16                'Convert calculated checksum to first hax character

IF ChckHex  < 10 THEN

    LET ChckHex = ChckHex + "0"

ELSE

    LET ChckHex = ChckHex + "7"

ENDIF

LET bptr = Msg_End + 2                  'Address of first checksun byte, which are in hex

LET I_tmp = @bptrinc                    'first Checksum character

IF ChckHex <> I_tmp THEN End_Interrupt

LET ChckHex = ChckSum & $F                'Convert calculated checksum to secong hax character

IF ChckHex  < 10 THEN

    LET ChckHex = Chckhex + "0"

ELSE

    LET ChckHex = ChckHex + "7"

ENDIF

LET I_tmp = @bptr                 'second Checksum character

IF ChckHex <> I_tmp THEN End_Interrupt


rem Store the desired data values

timeout:

LET NewData = 1

SELECT Key_Code

    CASE= "w"                 'Put the Mobile Logger data into memory at 34, no commas    

        LET bptr = 34        

        FOR MsgLoc = Msg_Start TO Msg_End

            PEEK MsgLoc,I_Tmp

            IF I_Tmp <> "," THEN            '12/14/2018 allow space and minus

                LET @bptrinc = I_Tmp

                IF bptr = 42 OR bptr = 50 THEN

                    LET @bptrinc = "."

                ENDIF

            ENDIF

        NEXT

    CASE "s"                 'Put the Solar Trnsmitter data into memory at 54

        LET bptr = 54

        FOR MsgLoc = Msg_Start TO Msg_End

            PEEK MsgLoc,I_Tmp

            IF I_Tmp >= "0" AND I_Tmp <= "9" THEN

                LET @bptrinc = I_Tmp

                IF bptr = 64 THEN

                    LET @bptrinc = "."

                ENDIF

            ENDIF

        NEXT

    CASE "t"                 'Put the time and date into memory at 67    

        LET bptr = 67    

        FOR MsgLoc = Msg_Start TO Msg_End

            PEEK MsgLoc,I_Tmp

            IF I_Tmp >= "0" AND I_Tmp <= "9" THEN

                LET @bptrinc = I_Tmp

            

                IF bptr = 69 THEN

                    LET @bptrinc = "/"

                ENDIF

                IF bptr = 74 THEN

                    LET @bptrinc = ":"

                ENDIF

            ENDIF

        NEXT

    CASE "u"                'The garage fan control reports the position of the door    

        LET MsgLoc = MsgBase + 14

        PEEK MsgLoc,I_tmp    

        POKE 85,I_tmp

        IF I_tmp = "D" THEN

            POKE 86,"O","W","N"

        ELSE

            POKE 86,"P"," "," "

        ENDIF

    CASE  "Q"                            'Gate open

        POKE 80,"O","P","E","N" 

    CASE  "B"

        POKE 80,"S","H","U","T"

ELSE

    LET NewData = 0

ENDSELECT

LET Msg_End = MsgBase + 25

SERTXD (Key_Code,",")

FOR MsgLoc = Msg_Start TO Msg_End

    PEEK MsgLoc,I_tmp

    IF I_tmp < " " THEN EXIT

    SERTXD (I_tmp)

NEXT

SERTXD (13,10)

IF NewData = 1 THEN

        GOSUB Update

ENDIF

End_Interrupt:

LOW TP

LET bptr = MSGBase

FOR I_tmp = 0 TO 28

    LET @bptrinc = ":"

NEXT

SETINT %00000100,%00000100    'Interrupt when Integrator high


RETURN