;********************************************************************************* ; gpspeed-test-datalog GpSpeed simple GpSpeedDataLog test program ; Terry@RotaryRacer, 2015-11-28 ;********************************************************************************* ; ; This is a basic test/demo example for the GpSpeedDataLog add on board. ; It sets up the real time clock to a fixed date and time. This code can be ; commented out once the date and time has been set once. ; It then writes then reads some data to/from each of the EEPROM chips, and ; compares what it reads from the expected values. It prints if the chip was present. ' Then it outputs the date and time in a loop. ; It prints information to the Picaxe serial/debug port. ; So the user must enable the terminal debug window in the Picaxe programming ; software to use this program. Note on a picaxe-28X2 the baud rate will be 9600. ; ; Note, when the picaxe serial cable is used as a serial debug port for inputing typed data ; from the user as it is in this program, then the picaxe cannot be programmed once the program ; has started. To program it in this case: Start the programming and then press the ; GpSpeed reset button. There is a small window of opportunity when the picaxe starts up were ; it can be programmed in this case. ; ; ; Uses fixed point scaled variables in 16bit integers for some things. These are scaled by 100. ; So 12.34 Volts is stored as 1234. ; ; For: PICAXE-28X2 (PIC18F25K22) ; ; GpSpeed pins are: ; B.1 LED ; C.2 Motor PWM ; C.1 Fan PWM ; A.0 Analogue Input 0, I0, throttle ; A.1 Analogue Input 1, I1, misc ; A.2 Analogue Input 2, Voltage measurement ; A.3 Analogue Input 3, Current measurement (Hall effect) ; B.4 Analogue/Digital Input, I2 ; ; B.2 Analogue Input 8, Current measurement (Mosfet) ; B.0 Error, error from Motor PWM ; C.3 I2C Clk ; C.4 I2c Dat ; C.0 User 0, I2c Int ; B.3 User 1 ; C.6 SER1 TX ; C.7 SER1 RX ; ; PWM range at 20kHz: 0 - 400 ; ; Compile time options ; Symbols for pin names symbol pinLed = B.1 ; The LED pin symbol pinPwmMotor = C.2 ; The motors PWM pin symbol pinPwmFan = C.1 ; The fans PWM pin ; Symbols to allocate variables. Variables w0-w7 (b0 - b15) are used as temporary variables symbol year = b16 ; The year symbol month = b17 ; The month symbol day = b18 ; The day symbol hour = b19 ; The hour symbol minute = b20 ; The minute symbol second = b21 ; The second symbol throttle = w11 ; The throttle input value 0 - 1000 symbol throttle.lsb = b22 symbol throttle.msb = b23 symbol voltage = w12 ; The battery voltage scaled by 100 symbol voltage.lsb = b24 symbol voltage.msb = b25 symbol current = w13 ; The battery currents scaled by 100 symbol current.msb = b26 symbol current.lsb = b27 symbol speed = w14 ; The battery currents scaled by 100 symbol temperature = b30 ; The temperature reading symbol spare1 = b31 ; The temperature reading symbol logPos = w16 ; The current datalog write position symbol pos = w17 ; Position symbol tmp = w18 ; General purpose temporary value symbol loopCount = b38 ; Loop count ; Symbols for CPU's internal EEPROM symbol eepromLogPos = 0 ; The current position in the dataLog init: let adcsetup = %000000000001111 ; Initialises ADC inputs gosub logInit ; Setup the data log gosub rtcInit ; Initialise the real time clock loopCount = 0 ; goto eepromTest ; Ignore the setting of the RTC setTime: ; Setup the date/time to a fixed starting value sertxd ("Set RTC's date and time", 13, 10) year = 15 month = 12 day = 1 hour = 10 minute = 0 second = 0 gosub rtcWrite eepromTest: ; Chip 1 hi2csetup i2cmaster, $A0, i2cslow, i2cword w0 = 0 hi2cout w0, ($F1, $F2) pause 5 hi2cin w0, (b2, b3) if b2 = $F1 and b3 = $F2 then sertxd ("Chip1: ok", 13, 10) else sertxd ("Chip1: not present", 13, 10) endif ; Chip 2 hi2csetup i2cmaster, $A4, i2cslow, i2cword w0 = 0 hi2cout w0, ($F3, $F4) pause 5 hi2cin w0, (b2, b3) if b2 = $F3 and b3 = $F4 then sertxd ("Chip2: ok", 13, 10) else sertxd ("Chip2: not present", 13, 10) endif ; Chip 3 hi2csetup i2cmaster, $A8, i2cslow, i2cword w0 = 0 hi2cout w0, ($F5, $F6) pause 5 hi2cin w0, (b2, b3) if b2 = $F5 and b3 = $F6 then sertxd ("Chip3: ok", 13, 10) else sertxd ("Chip3: not present", 13, 10) endif ; Chip 1 hi2csetup i2cmaster, $AC, i2cslow, i2cword w0 = 0 hi2cout w0, ($F7, $F8) pause 5 hi2cin w0, (b2, b3) if b2 = $F7 and b3 = $F8 then sertxd ("Chip4: ok", 13, 10) else sertxd ("Chip4: not present", 13, 10) endif sertxd ("Test RTC", 13, 10) timeLoop: gosub rtcRead sertxd (#day, "/", #month, "/", #year, " ", #hour, ":", #minute, ":", #second) sertxd (13,10) pause 1000 goto timeLoop end ;****************************************************************************** ; RTC Subroutines ;****************************************************************************** ; ; Provides functions to read and write the date and time from the RTC. ; Note the RTC uses BCD (binary coded decimal) for its data rather than plain binary integers ; rtcInit: ; Initialises the RTC with a set date/time hi2csetup i2cmaster, $D0, i2cslow, i2cbyte return rtcSetTime: ; Hard coded date/time in BCD: sec, min, hour, wday, day, month, year, control: 15/12/01 12:00:00 hi2csetup i2cmaster, $D0, i2cslow, i2cbyte hi2cout 0, ($00, $00, $12, $01, $01, $12, $15, $00) return rtcRead: ; Reads the current date/time as integers into year,month,day,hour,minute,second hi2csetup i2cmaster, $D0, i2cslow, i2cbyte hi2cin 0, (b2, b3, b4) ; read sec, min, hour hi2cin 4, (b5, b6, b7) ; read day, month, year ; Convert BCD values to integers b1 = b2 & $0F ; Get the units second = b2 / 16 * 10 + b1 ; Get tens and add units b1 = b3 & $0F ; Get the units minute = b3 / 16 * 10 + b1 ; Get tens and add units b1 = b4 & $0F ; Get the units hour = b4 / 16 * 10 + b1 ; Get tens and add units b1 = b5 & $0F ; Get the units day = b5 / 16 * 10 + b1 ; Get tens and add units b1 = b6 & $0F ; Get the units month = b6 / 16 * 10 + b1 ; Get tens and add units b1 = b7 & $0F ; Get the units year = b7 / 16 * 10 + b1 ; Get tens and add units return rtcWrite: ; Writes the current date/time as integers from year,month,day,hour,minute,second to the RTC b1 = second // 10 ; Convert second to BCD b2 = second / 10 * 16 + b1 b1 = minute // 10 ; Convert minute to BCD b3 = minute / 10 * 16 + b1 b1 = hour // 10 ; Convert hour to BCD b4 = hour / 10 * 16 + b1 b1 = day // 10 ; Convert day to BCD b5 = day / 10 * 16 + b1 b1 = month // 10 ; Convert month to BCD b6 = month / 10 * 16 + b1 b1 = year // 10 ; Convert year to BCD b7 = year / 10 * 16 + b1 hi2csetup i2cmaster, $D0, i2cslow, i2cbyte hi2cout 0, (b2, b3, b4) ; write sec, min, hour hi2cout 4, (b5, b6, b7) ; write day, month, year return bcdToNum: b1 = b0 & $0F ; Get the units b0 = b0 / 16 * 10 + b1 ; Get tens and add units return rtcTest: ; Simple test loop reading the date and time and outputing it to the serial debug lines gosub rtcRead sertxd (#day, "/", #month, "/", #year, " ", #hour, ":", #minute, ":", #second, 13, 10) pause 1000 goto rtcTest ;****************************************************************************** ; Log Subroutines ;****************************************************************************** ; ; The data logs write position is stored in the CPU's internal EEPROM area as a ; 16 bit pointer to a complete 16 byte data record. ; Note that the CPU's internal EEPROM is reset to 0 when a new program is downloaded ; logInit: ; Initialise I2C bus, access to I2C EEPROM chips and read old logPos hi2csetup i2cmaster,$A0, i2cslow, i2cword read eepromLogPos, b0, b1 logPos = b1 << 8 | b0 return logReset: ; Reset data logging position to the start, 0 logPos = 0 b0 = logPos & $FF b1 = logPos >> 8 write eepromLogPos, b0, b1 return logAppend: ; Append a data log entry and increment the log position b0 = logPos >> 11 & $FE + $A0 w1 = logPos << 4 hi2csetup i2cmaster, b0, i2cslow, i2cword hi2cout w1, (year, month, day, hour, minute, second, throttle.lsb, throttle.msb, voltage.lsb, voltage.msb, current.lsb, current.msb) pause 5 ; It takes up to 5ms for the EEPROM chip to write the data logPos = logPos + 1 b0 = logPos & $FF b1 = logPos >> 8 write eepromLogPos, b0, b1 return logGet: ; Fetch a log entry from the location given in w0 b2 = w0 >> 11 & $FE + $A0 w0 = w0 << 4 hi2csetup i2cmaster, b2, i2cslow, i2cword hi2cin w0, (year, month, day, hour, minute, second, throttle.lsb, throttle.msb, voltage.lsb, voltage.msb, current.lsb, current.msb) return