'{$STAMP BS2sx} '{$PBASIC 2.5} 'Uses PCF8583 for RTC 'Connects to LCD via RS232 levels 'I2C devices RTC_Write CON %10100000 RTC_Read CON %10100001 'CONSTANTS SDA CON 5 'I2C Data line SCL CON 4 'I2C Clock line Control_Status_Reg CON 0 'RTC Control/Status Reg ADCclock CON 0 'P0 = Clock to TLC548 ADCdata CON 1 'P1 = Data from TLC548 ADCenable CON 2'P2 = CS on TLC548 Low = enabled 'VARIABLES adc_data VAR BYTE 'data from the ADC ack VAR BIT 'Acknowledge from the I2C bus I2C_data VAR BYTE 'Data to/from the I2C bus i VAR BYTE 'just a for loop variable LCDcharacter VAR BYTE BCD_data VAR BYTE regcount VAR BYTE Menu_level VAR NIB font VAR NIB minutes VAR BYTE hours VAR BYTE month VAR NIB monthcheck VAR NIB year_reg VAR BYTE year_offset VAR BYTE current_year VAR BYTE date_time_value VAR BYTE maxday VAR BYTE start VAR BYTE x VAR BYTE y VAR BYTE x1 VAR BYTE y1 VAR BYTE x2 VAR BYTE y2 VAR BYTE xplot VAR BYTE colour VAR BIT sync VAR BIT sample_previous VAR BYTE sample_now VAR BYTE DIRS=%0001111111111111 PAUSE 5000 'Allow display of Lennard Logo for a while xplot = 81 Main: GOSUB update_display regcount = 5 GOSUB Read_RTC year_offset = I2C_data >> 6 current_year = year_offset GOSUB Clear_display serout 3,240,[254] serout 3,240,[108] serout 3,240,[80] serout 3,240,[5] serout 3,240,[80] serout 3,240,[22] serout 3,240,[254] serout 3,240,[101] serout 3,240,[121] serout 3,240,[22] font = 3 GOSUB Set_Font y = 0 x = 0 GOSUB Place_at_Pixel regcount = 5 GOSUB update_display serout 3,240,[ "/"] regcount = 6 GOSUB update_display serout 3,240,[ "/20"] y = 0 x = 99 for i = 0 to 1 GOSUB Place_at_Pixel serout 3,240,[ ":"] x = 111 next font = 1 GOSUB Set_Font x = 0 y = 25 GOSUB Place_at_Pixel serout 3,240,[ "DATE/TIME"] Menu_level = 0 _loop: font = 1 GOSUB Set_Font y = 10 x = 0 GOSUB Place_at_Pixel regcount = 2 'read seconds register GOSUB read_RTC sample_now = I2C_data if sample_previous <> sample_now then 'has 1 second passed since last sample? LOW ADCenable SHIFTIN ADCdata, ADCclock, MSBPRE, [adc_data] HIGH ADCenable serout 3,240,[dec((ABS(adc_data)*100)/190), " deg C "] serout 3,240,[254] serout 3,240,[112] serout 3,240,[xplot] serout 3,240,[22-(ABS(adc_data)/16)] xplot = xplot + 1 endif sample_previous = sample_now if xplot > 121 then xplot = 81 'clear graph serout 3,240,[254, 120, 0] serout 3,240,[81,5,121,21] endif y = 0 font = 3 GOSUB Set_Font for i = 2 to 7 regcount = i if regcount = 2 then x = 115 endif if regcount = 3 then x= 103 endif if regcount = 4 then x= 91 endif if regcount = 5 then x= 0 endif if regcount = 6 then x= 13 endif if regcount = 7 then regcount = 5 GOSUB Read_RTC year_offset = I2C_data >> 6 'debug dec year_offset, 13 if year_offset <> current_year then current_year = year_offset regcount = 255 GOSUB Read_RTC year_reg = I2C_data year_reg.LOWNIB = year_reg.LOWNIB + 1 if year_reg.LOWNIB > 9 then year_reg.LOWNIB = 0 year_reg.HIGHNIB = year_reg.HIGHNIB + 1 endif if year_reg > %01001001 then year_reg = 0 'BCD for 49 'put value back in reg 255 GOSUB Write_RTC I2C_data = regcount GOSUB Write_data I2C_data = year_reg Gosub Write_data GOSUB StopI2C endif regcount = 255 x= 33 endif GOSUB Place_at_Pixel GOSUB update_display next font = 1 GOSUB Set_Font if IN13 = 0 then Act_on_button_0 if IN14 = 0 then Act_on_button_1 if IN15 = 0 then Act_on_button_2 GOTO _loop '*********************** LCD SUBROUTINES ********************************** Clear_display: serout 3,240,[ 254] '254 = command serout 3,240,[ 88] '88 = clear display RETURN Zero_Pixel: x = 0 y = 0 GOSUB Place_at_Pixel GOSUB update_display RETURN Place_at_Pixel: serout 3,240,[ 254] serout 3,240,[ 121] serout 3,240,[ x] serout 3,240,[ y] RETURN Set_Font: serout 3,240,[ 254] serout 3,240,[ 49] serout 3,240,[ font] RETURN Draw_line: serout 3,240,[ 254] serout 3,240,[ 99] serout 3,240,[ colour] serout 3,240,[ 254] serout 3,240,[ 108] serout 3,240,[ x1] serout 3,240,[ y1] serout 3,240,[ x2] serout 3,240,[ y2] RETURN SendtoLCD: serout 3,240,[ LCDCharacter] RETURN '^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LCD SUBROUTINES ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '*********************** I2C SUBROUTINES ********************************** 'Start Procedure. Set start condition on bus: SDA Hi-Lo while SCL Hi StartI2C: HIGH SDA HIGH SCL LOW SDA LOW SCL RETURN 'Stop Procedure. Set stop condition on bus: SDA Lo-Hi while SCL Hi StopI2C: LOW SDA HIGH SCL HIGH SDA RETURN 'Write Address/Data Procedure Write_data: shiftout SDA, SCL, msbfirst, [I2C_data] 'Check for Receiver Acknowledge RX_ACK: HIGH SDA DIRS=%0001111011111011 HIGH SCL ack = IN2 LOW SCL DIRS=%0001111111111111 'if ack = 1 then indicate_NO_ACK 'debug "Acknowledged", 13 'RETURN 'indicate_NO_ACK: ' debug "NO Acknowledge", 13 RETURN '^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I2C SUBROUTINES ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ '*********************** RTC SUBROUTINES *********************** update_display: GOSUB Write_RTC I2C_data = Control_Status_Reg GOSUB Write_data I2C_data = %00001000 'turn mask on, so we don't read day and year GOSUB Write_data Gosub Read_RTC 'units = i2c_data 'tens = i2c_data >> 4 BCD_data = i2c_data LCDCharacter = 48 + BCD_data.HIGHNIB 'tens GOSUB sendtoLCD LCDCharacter = 48 + BCD_data.LOWNIB 'units GOSUB sendtoLCD GOSUB Write_RTC I2C_data = Control_Status_Reg GOSUB Write_data I2C_data = 0 'turn mask off, so we can read day and year GOSUB Write_data GOSUB StopI2C return Write_RTC: GOSUB StartI2C i2c_data = RTC_Write GOSUB Write_data RETURN Read_RTC: GOSUB StartI2C I2C_data = RTC_Write GOSUB Write_data I2C_data = regcount GOSUB Write_data GOSUB StartI2C I2C_data = RTC_Read GOSUB Write_data shiftin SDA, SCL, msbPre, [I2C_data] GOSUB STOPI2C RETURN '^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RTC SUBROUTINES ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Act_on_button_0: 'if menulevel = x then go to associated routine if Menu_level = 0 then Menu_level = 1 'start = Set_date_and_time_menu2 x = 0 y = 25 GOSUB Place_at_Pixel serout 3,240,[ "Adjust "] x = 60 GOSUB Place_at_Pixel serout 3,240,[ ">"] x = 111 GOSUB Place_at_Pixel serout 3,240,[ "OK"] 'draw a line under the day colour = 1 x1 = 0 y1 = 5 x2 = 8 y2 = y1 GOSUB Draw_line checkbuttons: if IN13 = 0 then Act_on_button_0 if IN14 = 0 then Act_on_button_1 if IN15 = 0 then Act_on_button_2 'BUTTON 13, 0, 255, 0, ButtonWorkspace, 1, Act_on_button_0 'Check if the buttons have been pressed 'BUTTON 14, 0, 255, 0, ButtonWorkspace, 1, Act_on_button_1 'Check if the buttons have been pressed 'BUTTON 15, 0, 255, 0, ButtonWorkspace, 1, Act_on_button_2 goto checkbuttons endif if menu_level = 1 then 'check where the highlight line is font = 3 GOSUB Set_Font 'if highlight under day... if x1 = 0 then regcount = 6 'month register GOSUB Read_RTC month = I2C_data 'BCD format lookdown month, = [1,2,3,4,5,6,7,8,9,%00010000,%00010001,%00010010], monthcheck branch monthcheck, [day31,February,day31,day30,day31,day30,day31,day31,day30,day31,day30,day31] February: 'get value of year_reg to check for a leap year regcount = 255 GOSUB Read_RTC year_reg = I2C_data SELECT year_reg 'BCD format below CASE 0,4,8,%00010010,%00010110,%00100000,%00100100,%00101000,%00110010,%00110110,%0100000,%01000100,%01001000 goto leapyear ENDSELECT maxday = %00101000 '28 in BCD goto end_daycheck leapyear: maxday = %00101001 '29 goto end_daycheck day30: maxday = %00110000 '30 goto end_daycheck day31: maxday = %00110001 '31 end_daycheck: regcount = 5 GOSUB Zero_Pixel BCD_data.LOWNIB = BCD_data + 1 if BCD_data.LOWNIB = 10 then BCD_data.LOWNIB = 0 BCD_data.HIGHNIB = BCD_data.HIGHNIB + 1 endif if BCD_data > maxday then BCD_data = 1 x = 0 y = 0 GOSUB Update_set_date_and_time_display endif 'if highlight under month... if x1 = 12 then regcount = 6 x = 13 y = 0 GOSUB Place_at_Pixel GOSUB update_display BCD_data.LOWNIB = BCD_data.LOWNIB + 1 if BCD_data.LOWNIB = 10 then BCD_data.LOWNIB = 0 BCD_data.HIGHNIB = BCD_data.HIGHNIB + 1 endif if BCD_data > %00010010 then BCD_data = 1 GOSUB Update_set_date_and_time_display endif 'if highlight under year if x1 = 32 then regcount = 255 GOSUB Read_RTC year_reg = I2C_data x = 33 y = 0 GOSUB Place_at_Pixel GOSUB update_display BCD_data.LOWNIB = BCD_data.LOWNIB + 1 if BCD_data.LOWNIB = 10 then BCD_data.LOWNIB = 0 BCD_data.HIGHNIB = BCD_data.HIGHNIB + 1 endif if BCD_data > %01001001 then BCD_data = 0 GOSUB Update_set_date_and_time_display 'adjust year offset year_offset = -1 BCD_data = ((BCD_data.HIGHNIB * 10) + (BCD_data.LOWNIB)) 'This line needed otherwise the For loop - converts BCD to binary for i = 0 to BCD_data 'which is used to set the offset - (bits 7,6 of RTC reg 5) year_offset = year_offset + 1 'will not work correctly if year_offset > 3 then year_offset = 0 next if BCD_data = 0 then year_offset = 0 current_year = year_offset 'Get current year offset and adjust it to the user's setting regcount = 5 GOSUB Read_RTC I2C_data.bit7 = 0 I2C_data.bit6 = 0 year_offset = I2C_data + (year_offset << 6) 'put value back in reg 5 GOSUB Write_RTC I2C_data = regcount GOSUB Write_data I2C_data = year_offset Gosub Write_data Gosub StopI2C endif if x1 = 90 then regcount = 4 x = 91 y = 0 GOSUB Place_at_Pixel GOSUB update_display BCD_data.LOWNIB = BCD_data.LOWNIB + 1 if BCD_data.LOWNIB = 10 then BCD_data.LOWNIB = 0 BCD_data.HIGHNIB = BCD_data.HIGHNIB + 1 endif if BCD_data > %00100011 then BCD_data = 0 GOSUB Update_set_date_and_time_display endif if x1 = 102 then regcount = 3 x = 103 y = 0 GOSUB Place_at_Pixel GOSUB update_display BCD_data.LOWNIB = BCD_data.LOWNIB + 1 if BCD_data.LOWNIB = 10 then BCD_data.LOWNIB = 0 BCD_data.HIGHNIB = BCD_data.HIGHNIB + 1 endif if BCD_data > %01011001 then BCD_data = 0 GOSUB Update_set_date_and_time_display endif endif goto checkbuttons Act_on_button_1: 'if menulevel = x then go to associated routine if menu_level = 1 then 'wipe line, move x1 and x2, redraw line colour = 0 GOSUB Draw_line colour = 1 x1 = x1 + 12 if x1 = 24 then x1 = 32 endif if x1 = 44 then x1 = 90 endif if x1 = 114 then x1 = 0 endif x2 = x1 + 8 GOSUB Draw_line pause 500 endif goto checkbuttons Act_on_button_2: pause 500 Menu_level = 0 goto Main Update_set_date_and_time_display: GOSUB Write_RTC I2C_Data = regcount GOSUB Write_data I2C_data = BCD_data GOSUB Write_data GOSUB StopI2C GOSUB Place_at_Pixel GOSUB update_display pause 500 RETURN