External Links

Creative Science Centre

 

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.

 

BV212

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

BV4111

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

BV4511/2

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

BV4618 Serial

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

BV4618 i2c

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

SV3

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