Devices
Updated drivers
BV4242
16x 2 display with keypad
// #include "http://www.byvac.com/mBlib/flb/Library/2016/lib_bv4242.bas"
http://www.byvac.com/downloads/BV4242/test.bas
Test will load the drive, run test(contrast), example:
test(30) // for a 5V system
test(170) // for a 3.3V system
BV4603/4
// #include "http://www.byvac.com/mBlib/flb/Library/2016/lib_bv4604dc.bas"
This just has the I2C DC drivers, initialise with the i2c adddress, the default is 100
- motor.init(i2c_address) // opens i2c and initialises
- motor.dca(power,direction) // power is 0 to 1023, direction is 0,1 or 2; 0 is off
- motor.dcb(power,direction) // power is 0 to 1023, direction is 0,1 or 2; 0 is off
- motor.dcab(power,direction) // power is 0 to 1023, direction is 0,1 or 2; 0 is off
dca is for a motor commecet to M1,M2
dcb is for a motor connected to M3,M4
Old Drivers
This is a collection of ByPic code that has been written to support ByVac devices. It is work in progress so please report any errors or updates.
SV3.bas has been modified to work with com 1 using the rookie access and so is compatible with MX1 and MX3 devices. This was updated on 3 June 2013, so if you have been using these prior to this date the browser cache will need clearing. Devices that use SV3 will not need updating.
http://byvac.com/mBlib/flb/Library/Devices/BV212/bv212.bas
// BV212 Serial version 1.0 // Requires sv3 #include "http://www.byvac.com/mBlib/flb/Library/Devices/SV3/sv3.bas" constant RELAYA 10 // (1 or 0 follows, 1 is on) <ACK> constant RELAYB 11 // (1 or 0 follows, 1 is on) <ACK> constant RELAYQ 20 // relay state <ACK> <state> constant RELAYOFF 21 // all relays off <ACK> constant SETIO 30 // sets input or output (H2byte) <ACK> constant GETIO 31 // gets value on port <ACK> <value> constant PUTIO 32 // sets port line to a value (chan) "(value)2 <ACK> constant ADCVAL 40 //gets ad channel value (chan) <ACK> <high byte> <low byte> constant ADCVOLT 41 //sets ref voltage (0,1 or 2) <ACK> constant DACOUTX 50 // outputs value to DAC (value) <ACK> constant DACOUTY 51 // outputs value to DAC (value) <ACK> // ***************************************************************************** // trun relay on, onn is 0 or 1 - no checking bad value will cause crash // returns 0 on error (no ACK received) // ***************************************************************************** function b12_rly(adr,relay,onn) return sv3_sendB(adr,RELAYA+relay,onn) endf // ***************************************************************************** // sets I/O to be in or out, the byte following the command is ASCII coded hex // returns 0 on error (no ACK received) // ***************************************************************************** function b12_setio(adr,byte) return sv3_sendH2(adr,SETIO,byte) endf // ***************************************************************************** // output to port. Outputs a PWM value to a specified port. The port is // specified in binary but the value is in ASCII coded hex // returns 0 on error (no ACK received) // ***************************************************************************** function b12_out(adr,chan,value) sv3_sendStart(adr, PUTIO) comout(UTARGET,chan) sv3_H2(value) comout(UTARGET,13) return sr_waitforACK() endf // ***************************************************************************** // DAC, chan is 0 or 1, chan is binary, value is H2 // ***************************************************************************** function b12_dac(adr,chan,value) return sv3_sendH2(adr,DACOUTX+chan,value) endf // ***************************************************************************** // ADC input, hets two bytes high and low // returns -1 on error // ***************************************************************************** function b12_adc(adr, chan) dim rv = - 1 if sv3_sendB(adr,ADCVAL,chan) = 1 then rv = comkey(1) << 8 rv = rv + comkey(1) endif return rv endf
http://byvac.com/mBlib/flb/Library/Devices/BV4111/bv4111.bas
// BV4111 serial relay controller with timer. // #include "http://www.byvac.com/mBlib/flb/Library/Devices/SV3/sv3.bas" // constant ADDRESS 'd' constant BV4111TO 1000 // ***************************************************************************** // simple intialise at 38400 // ***************************************************************************** function bv411_init() dim j, tell=0 for j = 1 to 3 // try 3 times if sv3_init(38400) = 1 then tell = 1 break endif next if tell = 0 then print "\nfailed to initialsie" endif endf // ***************************************************************************** // Turns on/off a relay ata agiven time. Specify relay as 1 to 8 // ***************************************************************************** function bv411_rly(relay,onn,when) dim a$[40] sr_clear(100) // clear buffer a$ = chr$(ADDRESS) + chr$(96+relay) + onn + "," + when + "\r" comouts(1,a$) if sr_Wack(BV4111TO) = 0 then print "\nError with relay "+chr$(96+relay) endif endf // ***************************************************************************** // gets a relay timer value // ***************************************************************************** function bv411_val(relay) dim b, a$[20] sr_clear(100) // clear buffer a$ = chr$(ADDRESS) + "r" + relay + "\r" comouts(1,a$) b = sv3_read$() return b endf // ***************************************************************************** // demo on an 8 relay system // ***************************************************************************** function bv411_demo() dim j bv411_init() print "\nTurning on relays - timed" for j = 1 to 8 print "\nrelay ",j bv411_rly(j,1,j*1000) next print "\nRelays will be turned off when relay h has been on for 1 second" while bv411_val(8) <> 0; wend wait(1000) for j = 1 to 8 print "\nrelay ",j bv411_rly(j,0,j*1000) next endf
http://byvac.com/mBlib/flb/Library/Devices/BV4511_2/bv4512_i2c.bas
// BV4512 I2C // Library exposing useful functions for the I2C version of this device. constant AD12 0x42 // easier to remember constant LINEWH 0x12 // line white horizontal constant LINEDH 0x13 // line dark horizontal constant LINEWV 0x14 // line white vertical constant LINEDV 0x15 // line dark vertical constant BOXWNF 0x16 // white no fill constant BOXDNF 0x17 // dark no fill constant BOXWWF 0x18 // white with fill constant BOXDWF 0x19 // dark with fill // ***************************************************************************** // Initialise i2c interface // ***************************************************************************** function d12_init() i2copen(1, 100000) endf // ***************************************************************************** // This just sends start and the command as it is used for all entries, when // used it needs to be finnished off with a i2cstop // ***************************************************************************** function d12_cmd(cmd) i2cstart(1,AD12) i2cputc(1,cmd) endf // ***************************************************************************** // clear screen with byte // 0 will clear the screen 0xff will white out // ***************************************************************************** function d12_cls(pattern) d12_cmd(0x10) i2cputc(1,pattern) i2cstop(1) endf // ***************************************************************************** // Text -- this is light text on dark backgrouns, use d12_cls(0) // ***************************************************************************** function d12_text(r,c,text$[30]) dim l=strlen(text$), j if r > 7 then r=7 endif if c > 20 then c=20 endif d12_cmd(0x25) // rc command i2cputc(1,r) i2cputc(1,c) i2cstop(1) d12_cmd(0x20) for j = 0 to l i2cputc(1,asc(text$,j)) next i2cstop(1) endf // ***************************************************************************** // Switches a single pixel on or off, if onn=1 then pixel on // ***************************************************************************** function d12_pix(x,y,onn) d12_cmd(0x11) i2cputc(1,x) i2cputc(1,y) i2cputc(1,onn) i2cstop(1) endf // ***************************************************************************** // Draws a line, the line depends on the command given // 0x12 white horizontal line // 0x13 dark horizontal line // 0x14 white versical line // 0x15 dark versical line // ***************************************************************************** function d12_line(cmd,x,y,len) d12_cmd(cmd) i2cputc(1,x) i2cputc(1,y) i2cputc(1,len) i2cstop(1) endf // ***************************************************************************** // Draws a box, the type of box depends on command given // 0x16 white box no fill // 0x17 dark box no fill // 0x18 white box with fill // 0x19 dark box with fill // ***************************************************************************** function d12_box(cmd,x,y,xLen,yLen) d12_cmd(cmd) i2cputc(1,x) i2cputc(1,y) i2cputc(1,xLen) i2cputc(1,yLen) i2cstop(1) endf
Updated June 2013, now uses com1_open() and so is compatible with MX1 & MX3
http://byvac.com/mBlib/flb/Library/Devices/BV4618/serial_bv4618.bas
// BV4618 LCD Character controller with 4x4 keypad interface // mBASIC // default address for this device is 0x62 'b' (8 bit) // Serial library and demo // SETUP // For serial to work best without hardware handshake, ACK is used for commands // This means that every command send to the BV4618 is acknoledged by the // BV4618. This is convenient as a routine can be set to wait for this ACK //============================================================================== constant AD18 0x62 constant ACK 42 // * constant TIMOUT 5000 // ================= INPUT ===================================================== // ***************************************************************************** // clears input buffer // ***************************************************************************** function d18_clear() dim tout=TIMOUT while tout > 1 while (comkey?(1) = 0) && (tout > 1) tout = tout - 1 wend if tout > 1 then comkey(1) tout=TIMOUT endif wend endf // debug utility function see() while comkey?(1) <> 0 print chr$(comkey(1)) wend endf // ***************************************************************************** // gets input from UART and finishes whan ack received or timout, whichever // comes first, returns with bytes received // ***************************************************************************** function d18_wait$(ack) dim tout=TIMOUT, rv$[25]="", k while tout > 0 if comkey?(1) <> 0 then k = comkey(1) if k <> ACK rv$=rv$+chr$(k) tout=TIMOUT else tout=-1 // finish endif endif tout=tout-1 wend return rv$ endf // ***************************************************************************** // General purpose command for sending and waiting for an ACK to come back. // Most commands will require esc[ first and also return an ACK. There are // some exceptions, sending text for example does not return an ACK // ***************************************************************************** function d18_cmd$(cmd$[25]) dim x$, rv$[25]="" x$ = "\27["+cmd$ comouts(1,x$) rv$ = d18_wait$(ACK) return rv$ endf // =============== OUTPUT ====================================================== // ***************************************************************************** // sets display to correct size - default is 2x16 // ***************************************************************************** function d18_set(cols, lines) dim col$=cols, li$=lines // needed as text comouts(1,"\27["+li$+"L") comouts(1,"\27["+col$+"c") endf // ***************************************************************************** // Initialise display setting to correct number of lines and columns // ***************************************************************************** function d18_init(cols, lines) comopen(1,115200,80) comout(1,13) // establish baud rate wait(400) // required to establish Baud rate d18_set(cols,lines) comouts(1,"\27["+ACK+"k") // set ACK charatcer endf // ***************************************************************************** // positions cursor // First postions are 1 so 1,1 is the home position // ***************************************************************************** function d18_pos(row,col) dim x$=row+";"+col+"H" // row and col converted to string d18_cmd$(x$) endf // ***************************************************************************** // Sends a string but will wait until the LCD has processed the string before // returning // ***************************************************************************** function d18_string(s$[25]) comouts(1,s$) // use wait to detect * after string comouts(1,"\27a") // forces bv4618 to return ACK d18_wait$(ACK) // stays until timeout or ack endf // ***************************************************************************** // clear screen and home cursor // [1] This is necessary to reset the internal line a column position of the // controller. // ***************************************************************************** function d18_cls() d18_cmd$("1E") // direct command 1 wait(200) // lcd needs time after cls d18_pos(1,1) // see note [1] endf // =================== DEVICE ================================================== // // ***************************************************************************** // dsiplays device and firmware on screen, assumes 16x2 // ***************************************************************************** function d18_sign() dim device$, fw$ device$=d18_cmd$("?31d") fw$=d18_cmd$("?31f") print device$,fw$ d18_cls() d18_string(format$("Device %s",device$)) d18_pos(2,1) // second row start d18_string(format$("Firmware %s",fw$)) endf // ================= KEYPAD ==================================================== // ***************************************************************************** // gets number of keys in buffer // ***************************************************************************** function d18_key?() dim k k = d18_cmd$("n") return k endf // ***************************************************************************** // returns key in buffer, returns 0 if no key pressed. Use d18_key? first to // make sure there is a key in the buffer // ***************************************************************************** function d18_key() dim k k = d18_cmd$("k") return k endf // ***************************************************************************** // clear key buffer // ***************************************************************************** function d18_keyclear() d18_cmd$("c") endf // =============== DEMO ======================================================== // ***************************************************************************** // gets a key and prints the scan code to the display ** Assumes 16 x 2 display // ***************************************************************************** function d18_demo() dim k d18_init(16,2) // 16 x 2 display d18_sign() wait(2000) // exit loop by keyboard input d18_cls() // clear screen for start d18_string("Enter key") while comkey?(2) = 0 // keypad loop if d18_key?() <> 0 d18_pos(1,11) d18_string(" ") // clear previous d18_pos(1,11) k = d18_key() d18_string(format$("%X",k)) endif wait(100) // give other I2C a chance wend endf
http://byvac.com/mBlib/flb/Library/Devices/BV4618/i2c_bv4618.bas
// BV4618 LCD Character controller with 4x4 keypad interface // mBASIC // default address for this device is 0x62 (8 bit) // I2C library and demo //============================================================================== constant AD18 0x62 // ***************************************************************************** // Sends string, can also be used for sending commands by using escape // character i.e. "\27 ** 0x1b will not work on early versions of mB // Increase string length for larger then 20 char displays // ***************************************************************************** function d18_string(s$[21]) i2cstart(1,AD18) i2cputs(1,s$) i2cstop(1) endf // ***************************************************************************** // Start a command to the display, all commands begin with 0x1b. This is only // the common start. It must be closed by the caller // ***************************************************************************** function d18_start(cmd) i2cstart(1,AD18) i2cputc(1,0x1b) i2cputc(1,cmd) endf // ============== INPUT ======================================================== // ***************************************************************************** // gets 1 byte following a command // ***************************************************************************** function d18_get8(cmd) dim r d18_start(cmd) i2cstop(1) i2cstart(1,AD18+1) // read address i2cgetc(1,?r,10000,1) i2cstop(1) return r endf // ***************************************************************************** // gets 2 bytes (16 bit value) following a command // ***************************************************************************** function d18_get16(cmd) dim r, rv d18_start(cmd) i2cstop(1) i2cstart(1,AD18+1) // read address i2cgetc(1,?r,10000,0) // high byte rv = r << 8 i2cgetc(1,?r,10000,1) // low byte rv = rv + r i2cstop(1) return rv endf // ============= OUTPUT ======================================================== // ***************************************************************************** // sets display to correct size - default is 2x16 // ***************************************************************************** function d18_set(cols, lines) d18_start(0x30) i2cputc(1,lines) i2cstop(1) d18_start(0x31) i2cputc(1,cols) i2cstop(1) endf // ***************************************************************************** // Initialise display setting to correct number of lines and columns // ***************************************************************************** function d18_init(lines, cols) i2copen(1, 100000) d18_start(0x43) // reset just in case i2cstop(1) wait(500) // required after reset d18_set(lines,cols) endf // ***************************************************************************** // positions cursor // First postions are 1 so 1,1 is the home position // ***************************************************************************** function d18_pos(row,col) d18_start(0x24) i2cputc(1,row) i2cputc(1,col) i2cstop(1) endf // ***************************************************************************** // clear screen and home cursor // [1] This is necessary to reset the internal line a column position of the // controller. // ***************************************************************************** function d18_cls() d18_string("\27\1\1") // direct command 1 wait(200) // lcd needs time after cls d18_pos(1,1) // see note [1] endf // =================== DEVICE ================================================== // // ***************************************************************************** // dsiplays device and firmware on screen, assumes 16x2 // ***************************************************************************** function d18_sign() dim device, fw, t device=d18_get16(0x40) fw=d18_get16(0x41) d18_cls() d18_string(format$("Device %d",device)) d18_pos(2,1) // second row start t = fw >> 8 d18_string(format$("Firmware %d",t)) t = fw&0xff d18_string(format$(".%d",t)) endf // ================= KEYPAD ==================================================== // ***************************************************************************** // gets number of keys in buffer // ***************************************************************************** function d18_key?() dim k k = d18_get8(0x10) return k endf // ***************************************************************************** // returns key in buffer, returns 0 if no key pressed. Use d18_key? first to // make sure there is a key in the buffer // ***************************************************************************** function d18_key() dim k k = d18_get8(0x11) return k endf // ***************************************************************************** // clear key buffer // ***************************************************************************** function d18_keyclear() d18_start(0x14) i2cstop(1) endf // =============== DEMO ======================================================== // ***************************************************************************** // gets a key and prints the scan code to the display ** Assumes 16 x 2 display // ***************************************************************************** function d18_demo() dim k d18_init(16,2) // 16 x 2 display d18_sign() wait(2000) // exit loop by keyboard input d18_cls() // clear screen for start d18_string("Enter key") while comkey?(2) = 0 // keypad loop if d18_key?() <> 0 d18_pos(1,11) d18_string(" ") // clear previous d18_pos(1,11) k = d18_key() d18_string(format$("%X",k)) endif wait(100) // give other I2C a chance wend endf
Updated June 2013 to use com1. This will now work unchanged with MX1 and MX3 devices.
http://byvac.com/mBlib/flb/Library/Devices/SV3/sv3.bas
// Serial version 3, alternative to IASI protocol as found on some ByVac // boards // version 1.0 November 2012 // // This code includes its own serial utilities. There are also a function for // setting the system eeprom values // // constant UTARGET 1 // this is the target uart constant UBUFFER 70 // buffer size constant TIMEOUT 10000 constant ACK 6 constant NACK 0x15 // ============================================================================= // sr_ are serial com port utilities // ============================================================================= // ***************************************************************************** // A simple utility to see what is in the UART input buffer // ***************************************************************************** function sr_see() dim tout=TIMEOUT, k while tout > 0 if comkey?(UTARGET) <> 0 k = comkey(UTARGET) print format$("%c",k) tout=5000 endif tout=tout-1 wend endf // ***************************************************************************** // gets a single char with time out, returns 1 if it has sucessfuly got a // byte. // Use in the form: // if sr_getc(?value) = 1 // then value containd valid byte // ***************************************************************************** function sr_getc(c) dim tout=TIMEOUT, rv=0 while tout > 0 if comkey?(UTARGET) <> 0 @c = comkey(UTARGET) rv = 1 break endif tout=tout-1 wend return rv endf // ***************************************************************************** // Clears input buffer // timeout of 5000 gives about 1 second or less // ***************************************************************************** function sr_clear(timeout) dim tout=timeout, k while tout > 0 if comkey?(UTARGET) <> 0 k = comkey(UTARGET) tout=5000 endif tout=tout-1 wend endf // ***************************************************************************** // Waits for ACK or NACK, fixed timeout // return 1 if ACK 0 if NACK or nothing recieved // ***************************************************************************** function sr_Wack(timeout) dim t = timeout, rv = 0, k while t > 0 if comkey?(UTARGET) <> 0 then k = comkey(UTARGET) if k = ACK then rv = 1 break endif t = timeout endif t = t - 1 wend return rv endf // ============================================================================= // sv3 are functions required for SV3 // ============================================================================= // ***************************************************************************** // starts a command, all commands begin with an address and cmd // ***************************************************************************** function sv3_start(adr,cmd) sr_clear(100) comout(UTARGET,adr) comout(UTARGET,cmd)) endf // ***************************************************************************** // reads from input until ack or timeout into buffer // returns number of characters read, thus 0 on error // ***************************************************************************** function sv3_read$() dim tout=TIMEOUT, k, rv$[80]="" while tout > 0 if comkey?(UTARGET) <> 0 k = comkey(UTARGET) if k = ACK then break endif rv$ = rv$ + chr$(k) endif tout=tout-1 wend return rv$ endf // ***************************************************************************** // gets device ID, returns string // ***************************************************************************** function sv3_ID$(adr) sv3_start(adr,'D') comout(UTARGET,13) return sv3_read$() endf // ***************************************************************************** // gets firmware version, returns string // ***************************************************************************** function sv3_firmware$(adr) sv3_start(adr,'V') comout(UTARGET,13) return sv3_read$() endf // ***************************************************************************** // reads eeprom // ***************************************************************************** function sv3_readEE$(adr,start,bytes) dim a$[20] a$ = start + "," + bytes sv3_start(adr,'R') comouts(UTARGET,a$) comout(UTARGET,13) return sv3_read$() endf // ***************************************************************************** // Initialise now needs at least 3 CR to be sent. Also very important there // must be 5ms between each CR // returns 1 on sucess // ***************************************************************************** function sv3_init(baud) dim sends, v, rv = 0 comclose(1) com1_open(baud,UBUFFER) sr_clear(200) for sends = 1 to 5 comout(1,13) wait(5) if sr_getc(?v) = 1 then if v = '*' //print "\nInitialised" rv = 1 break endif endif next wait(10); sr_see() return rv endf // ***************************************************************************** // gets address of device // returns -1 on error // ***************************************************************************** function sv3_adr() dim a, rv = -1 sr_clear(200) comout(UTARGET,1) comout(UTARGET,13) // no ack returned wait(250) // needs to be 440 if sr_getc(?a) = 1 then rv = a endif return rv endf // ***************************************************************************** // resets device // ***************************************************************************** function sv3_reset() comout(UTARGET,3) comout(UTARGET,13) wait(10) endf // ***************************************************************************** // writes value to eeprom, location and value are H2 type ASCII coded hex values // command format <adr>'W'"l","v" // ***************************************************************************** function sv3_writeEE(adr,v,location) dim a$[30] sv3_start(adr,'W') a$ = location + "," a$ = a$ + v + "\r" comouts(UTARGET,a$) // whole command if sr_Wack(TIMEOUT) = 0 then print "\nProblem with write eeprom command" return 0 endif return 1 endf // ***************************************************************************** // a utility that gets a number form the user // ***************************************************************************** function input(prompt$[80]) dim k=0, a$[80] print prompt$ while k <> 13 while comkey?(2) = 0; wend // wait k = comkey(2) print chr$(k) // echo a$ = a$ + chr$(k) wend return a$ endf // ***************************************************************************** // function to change system eeprom values // ***************************************************************************** function sv3_eeEdit(adr) dim val, loc dim p=0, j=0, ee$[80] ee$ = sv3_readEE$(100,0,20) if strlen(ee$) > 0 then while p >= 0 print "\n",j print " ",token$(ee$,?p,',') j = j + 1 wend endif loc = input("\nEnter address number to change ") if loc > 21 || loc < 0 then print "\nError 0 to 20 needed" return endif val = input("\nNew value between 0 and 256 DECIMAL ") sv3_writeEE(adr,val,loc) endf