def climb_thread(fg_climb): """ Climb Rate loop thread. """ while True: # Read variable variometer = fg_climb['/instrumentation/vertical-speed-indicator/indicated-speed-fpm'] # Variometer, climb rate variometer_deg_cal = 90.0 + (variometer * 0.0225) # Travel snubber variometer_deg_cal = snubber(variometer_deg_cal) TINK.setSERVO(0,1,variometer_deg_cal)
def art_hor_thread(fg_art_hor): """ Artificial Horizon loop thread. """ # 1/2 of an artificial horizon while True: # Read Variable roll_deg = fg_art_hor['/instrumentation/attitude-indicator/indicated-roll-deg'] # Reverse and calibrate, FG is 45 0 -45, PiPlate is 0 180deg roll_deg_cal = 90.0 - roll_deg # Travel snubber roll_deg_cal = snubber(roll_deg_cal) TINK.setSERVO(0,8,roll_deg_cal)
def message_record(self, message): if self.thread.isRunning(): c = '{0:f},{1:d},{2:f},{3:x},'.format(message.timestamp, self.count, message.arbitration_id, message.dlc) data='' viscosity=0 density=0 dielectric_constant=0 oil_temp=0 Rp = 0 status_code=0 if message.dlc == 8: if message.arbitration_id == float.fromhex('1CFD083F'): viscosity = int('{0:x}{1:x}'.format(message.data[1],message.data[0]), 16)/63.9994 density = int('{0:x}{1:x}'.format(message.data[3],message.data[2]), 16)/32762.6478988 dielectric_constant = int('{0:x}{1:x}'.format(message.data[5],message.data[4]), 16)/8191.9153277 elif message.arbitration_id == float.fromhex('18FEEE3F'): oil_temp = (int('{0:x}{1:x}'.format(message.data[3],message.data[2]), 16)/32.0)-273.0 elif message.arbitration_id == float.fromhex('18FF313F'): status_code = int('{0:x}'.format(message.data[0]), 16) elif message.arbitration_id == float.fromhex('18FFFF3F'): Rp = (int('{0:x}{1:x}{2:x}{3:x}'.format(message.data[3], message.data[2], message.data[1], message.data[0]), 16)*1000.0) + 100000 else: self.log_message.emit("incorrect arbitration id transmitted") else: self.log_message.emit("Incorrect number of channels received") for i in range(message.dlc ): data += '{0:x}'.format(message.data[i]) data += ("%11.6f,%10.8f,%10.8f,%10.5f,%0d,%0d" % (viscosity, density, dielectric_constant, oil_temp, status_code, Rp)) if status_code != 0: self.log_message.emit("sensor reports error code %d" % (status_code)) outstr = c+data if (self.AIEnabled == 1): volts = TINK.getADC(0,1) outstr = outstr+', '+ str(volts) volts = TINK.getADC(0,1) outstr = outstr+', '+ str(volts) volts = TINK.getADC(0,1) outstr = outstr+', '+ str(volts) volts = TINK.getADC(0,1) outstr = outstr+', '+ str(volts) self.count += 1 try: if status_code != 0 or message.arbitration_id == 486344767 or message.arbitration_id == 419360319 or message.arbitration_id == 419430207: print(outstr,file = self.outfile) # Save data to file self.log_message.emit(outstr) except: self.log_message.emit("Canbus RX Thread Error")
def slow_gauge(fg_slow): """ A place for slow changing instruments. """ while True: # Fuel gauge # Consider tank select switch tank_switch = TINK.getPOT(0,4) if tank_switch <= 5: fuel_gauge = fg_slow['/consumables/fuel/tank/level-gal_us'] elif tank_switch > 5 and tank_switch <= 40: fuel_gauge = fg_slow['/consumables/fuel/tank[1]/level-gal_us'] elif tank_switch > 40 and tank_switch <= 80: fuel_gauge = fg_slow['/consumables/fuel/tank[2]/level-gal_us'] else: fuel_gauge = fg_slow['/consumables/fuel/tank[3]/level-gal_us'] # Normalize fuel gauge value fuel_gauge_deg_cal = fuel_gauge * 0.9 # Travel snubber fuel_gauge_deg_cal = snubber(fuel_gauge_deg_cal) TINK.setSERVO(0,2,fuel_gauge_deg_cal) time.sleep(1.0)
def int_apionics(): """ Initialize the servos and define channels. """ # Bank (roll_deg), channel 8, servo control, settle time TINK.setMODE(0,8,'servo') time.sleep(0.5) # Variometer, channel 1, servo control, settle time TINK.setMODE(0,1,'servo') time.sleep(0.5) # Fuel gauge, channel 2, servo control, settle time TINK.setMODE(0,2,'servo') time.sleep(0.5)
def dout8Change(): #Callback function for digital output 8 if(doutCnt8.value=='SET'): TINK.setDOUT(0,8) else: TINK.clrDOUT(0,8)
import piplates.TINKERplate as TINK #import TIINKERplate module import math #import math module - needed for sine and pi import time #import the time module - needed for sleep Mag = 10 N = 360 TINK.openMETER() #create a panel meter with the gefault of a single line while (True): #Loop forever for i in range(N): #do this 360 times val = Mag * math.sin(2 * math.pi * i / 360) TINK.setMETER(val, 'volts', 'Sine Data:') time.sleep(0.05)
def pwm6Change(): #Callback function for pwm output 6 val=int(dpwm6.value) TINK.setPWM(0,6,val)
def dashboard(): #update all periodic ana log and digital inputs adc1=TINK.getADC(0,1) #\ adc2=TINK.getADC(0,2) # \___Read all analog inputs adc3=TINK.getADC(0,3) # / adc4=TINK.getADC(0,4) #/ adcVal1.value=str("{:2.3f}".format(TINK.getADC(0,1))) #\ adcVal2.value=str("{:2.3f}".format(TINK.getADC(0,2))) # \_Format analog values update data on screen adcVal3.value=str("{:2.3f}".format(TINK.getADC(0,3))) # / adcVal4.value=str("{:2.3f}".format(TINK.getADC(0,4))) #/ dinVal1.value=str(TINK.getDIN(0,1)) #\ dinVal2.value=str(TINK.getDIN(0,2)) # \___Read all digital inputs and update data on screen dinVal3.value=str(TINK.getDIN(0,3)) # / dinVal4.value=str(TINK.getDIN(0,4)) #/
def main(): # log start up message logging.info("***************************************************************") logging.info("Data Collector has started") logging.info("Running %s", __file__) logging.info("Working directory is %s", os.getcwd()) logging.info("SQLITE Database file is %s", dbfilename); localipaddress = "IP: Unknown" try: hostname = socket.gethostname() externalip = get('https://api.ipify.org').text s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('8.8.8.8', 1)) # connect() for UDP doesn't send packets localipaddress = s.getsockname()[0] logging.info("Hostname is %s", hostname) logging.info("Local IP is %s and external IP is %s", localipaddress, externalip) except Exception as e: logging.exception("Exception occurred") logging.error("Unable to get network information") # close any open db connections # create connection to our database mydb = createConnection(dbfilename) if mydb is not None: # create table createTable(mydb) mydb.commit() # insert some values lastRowId = countRows(mydb) logging.info("Data points in table: %d", lastRowId) rowcount = lastRowId # create a temperature service instance temperatureService = None try: temperatureService = TemperatureService() except Error as e: logging.error("Unable to create temperature service") # create a voltage service instance voltageService = None try: voltageService = ADCService() except Exception as e: logging.error("Unable to create ADC service") # try to access TinkerPlate tinkerplate = None try: tinkerplate = tink tinkerplate.setDEFAULTS(0) logging.info("TinkerPlate found") except Exception as e: logging.error("Unable to get Tinker Plate") tinkerplate = None # counter for measurement iterations iteration = 1 # keep running until ctrl+C while True: # increase iteration count iteration = iteration + 1 # toggle LED to indicate action if tinkerplate != None: try: tink.setLED(0, 0) except Exception as e: pass # read temperature values dataSetIndex = 0 if (temperatureService != None): tempsString = "" temperatureService.readSensors() now = datetime.datetime.now() nowDateTime = str(now) nowDate = now.strftime("%Y-%m-%d") nowTime = now.strftime("%H:%M:%S") try: values = temperatureService.getValues() sensorId = 1 for value in values: row = (lastRowId + 1, sensorId, nowDate, nowTime, nowDateTime, value) lastRowId = insertRow(mydb, row) rowcount = rowcount + 1 tempsString = tempsString + str(value) + " " sensorId = sensorId + 1 except Exception as e: logging.error("Unable to read values and to add data to database") logging.info("Try to recreate DB file") mydb.close() # create table mydb = createConnection(dbfilename) createTable(mydb) mydb.commit() # get the last row id lastRowId = countRows(mydb) logging.info("Data points in table: %d", lastRowId) rowcount = lastRowId # toggle LED to indicate action if tinkerplate != None: try: tink.clrLED(0, 0) except Exception as e: pass # readvoltage values now = datetime.datetime.now() nowDateTime = str(now) nowDate = now.strftime("%Y-%m-%d") nowTime = now.strftime("%H:%M:%S") values = [] try: if (voltageService != None): values = voltageService.getValues() for value in values: row = (lastRowId + 1, sensorId, nowDate, nowTime, nowDateTime, value) lastRowId = insertRow(mydb, row) sensorId = sensorId + 1 rowcount = rowcount + 1 except Exception as e: logging.error("Unable to read voltage") # read voltage values from TinkerPlate try: if (tinkerplate != None): channelid = 1 #voltagefactors = [1220 / 220, 1220 / 220, 1333, 1] voltagefactors = [1220 / 220, 1220 / 220, 1, 1] values = tinkerplate.getADCall(0) for value in values: row = (lastRowId + 1, sensorId, nowDate, nowTime, nowDateTime, value * voltagefactors[channelid - 1]) lastRowId = insertRow(mydb, row) sensorId = sensorId + 1 rowcount = rowcount + 1 channelid = channelid + 1 except Exception as e: logging.error("Unable to read from TinkerPlate") try: # commit the DB write mydb.commit() except Exception as e: logging.exception("Exception occurred while trying to commit to DB") time.sleep(15) mydb.close() if einkDisplay != None: einkDisplay.turnOff() logging.info("Data Collector main loop has terminated, database is closed")
import piplates.TINKERplate as TINK #load TINKERplate module import time #load time functions d = '\u00b0' #create the degree symbol TINK.setMODE(0, 1, 'temp') #setmode while (True): #loop forever t = TINK.getTEMP(0, 1) #fetch temperature #print to the console print('Time:', time.ctime(), ' - Temperature is:', t, d + 'F') #print to the console time.sleep(1) #delay 1 second
dDanger=20.0 stringR = [0xFF,0x0,0x0] #Create a list of red LEDs patterns for i in range(3): stringR=stringR+stringR stringY = [0xFF,0xFF,0x00] #Create a list of yellow LEDs patterns for i in range(3): stringY=stringY+stringY stringG = [0x0,0xFF,0x00] #Create a list of green LEDs patterns for i in range(3): stringG=stringG+stringG stringO = [0x0,0x00,0x00] #Create a list of off LEDs patterns for i in range(3): stringO=stringO+stringO TINK.setDEFAULTS(0) #set all Digital I/O ports to their default states TINK.setMODE(0,1,'rgbled') #set the mode of Digital I/O port 1 to RGB LED TINK.setMODE(0,5,'dout') #set the mode of Digital I/O port 5 to digital output TINK.setMODE(0,78,'range') #set the mode of Digital I/O channel pair 78 to range dist=0.0 #initialize global variables bToggle=False blink=False alarm=False zone=0 while(True): #start repeating loop dist=TINK.getRANGEfast(0,78) #print(dist,zone) #uncomment for debugging try: blink=False #assume no blinking alarm=False #assume no alarm
import piplates.TINKERplate as TINK import time #create battery state thresholds VL = 1.2 VH = 1.4 TINK.setDEFAULTS(0) TINK.setMODE(0, 1, 'rgbled') #set Digital I/O port to display Neopixels red = [255, 0, 0] #define the red color mix yel = [255, 255, 0] #define the yellow color mix grn = [0, 255, 0] #define the green color mix off = [0, 0, 0] #define an off LED blank = off + off + off + off + off + off + off + off #create a set of OFF LEDs strip = red + red + red + red + yel + yel + grn + grn #create the battery status lights while (True): bat = TINK.getADC(0, 1) #read analog channel 1 #scale the data to an integer in the range of 0 through 7 temp = bat - 0.8 #we will only look at the range from 0.8 volts to 1.6 if (temp < 0): index = 0 #if the measured voltage is negative, set index to 0 else: #otherwise, convert the voltage to a list index index = int(temp * 10) if (index > 7): #limit the maximum index to 7 index = 7 batstrip = strip[0:3 * (index + 1)] + blank[0:3 * (8 - index)] #assembled string TINK.setRGBSTRING(0, 1, batstrip) #send string data to TINKERplate time.sleep(.5) #delay and repeat
import piplates.TINKERplate as TINK import time for i in range(100): #Repeat this loop 100 times TINK.clrLED(0,0) #LED off time.sleep(0.05) #sleep for 50msec TINK.setLED(0,0) #LED on time.sleep(0.05) #sleep for 50msec print ("I'm all blinked out!")
TINK.setPWM(0,6,val) def dout7Change(): #Callback function for digital output 7 if(doutCnt7.value=='SET'): TINK.setDOUT(0,7) else: TINK.clrDOUT(0,7) def dout8Change(): #Callback function for digital output 8 if(doutCnt8.value=='SET'): TINK.setDOUT(0,8) else: TINK.clrDOUT(0,8) #Initialize TINKERplate Digital I/O lines TINK.RESET(0) time.sleep(0.5) TINK.setMODE(0,1,'din') TINK.setMODE(0,2,'din') TINK.setMODE(0,3,'din') TINK.setMODE(0,4,'din') TINK.setMODE(0,5,'pwm') TINK.setMODE(0,6,'pwm') TINK.setMODE(0,7,'dout') TINK.setMODE(0,8,'dout') #Define the overall characteristics of our dashboard including size and background color app = App(title="TINKERplate Dashboard",bg="white",layout="grid",width=750,height=360) dashTitle=Text(app,text= "",width="fill",grid=[0,0,5,1]) #insert the callout image on the left side
import piplates.TINKERplate as TINK import time TINK.setDEFAULTS(0) #initialize Digital I/O ports TINK.setMODE(0, 2, 'din') #set port 2 as an input for the motion sensor TINK.setMODE(0, 3, 'dout') #set port 3 as an output for the siren while (True): motion = TINK.getDIN(0, 2) #read motion sensor status if (motion == 1): #if motion detected TINK.relayON(0, 1) #turn on lamp TINK.setDOUT(0, 3) #turn on siren else: #if no motion TINK.relayOFF(0, 1) #turn off lamp TINK.clrDOUT(0, 3) #turn off siren time.sleep(0.1) #wait 100msec and repeat
import piplates.TINKERplate as TINK import time d = '\u00b0' #create the degree symbol tripTEMP = 78 #this is the temperature we will operate around hysteresis = 1 #we will add a small amount of hysteresis to avoid chatter threshold = tripTEMP - hysteresis #the on/off threshold is the tripTEMP +/- the hysteresis fanON = True #initialize flag and.. TINK.relayON(0, 1) #turn on fan TINK.setDEFAULTS(0) #set all Digital I/O ports to their default states TINK.setMODE(0, 1, 'temp') #set the mode of Digital I/O port 1 to temperature TINK.openMETER(1) #Create a display meter on the screen TINK.setTITLE('TINKERplate Demo') TINK.setCOLOR((255, 0, 0)) #Set meter text color to RED to indicate warm range while (True): #start loop temp = TINK.getTEMP(0, 1) #collect temperature data TINK.setMETER(temp, d + 'F', 'Temperature:') if (fanON): if (temp < threshold): #if on and temp is below threshold: fanON = False #clear state TINK.relayOFF(0, 1) #turn off fan threshold = tripTEMP + hysteresis #set high threshold TINK.setCOLOR( (0, 0, 255)) #Set meter text color to BLUE to indicate cool range print("Temperature:", temp, ", Fan Off") #indicate the state change
def message_record(self, message): if self.thread.isRunning(): c = '{0:f},{1:d},{2:f},{3:x},'.format(message.timestamp, self.count, message.arbitration_id, message.dlc) data = '' viscosity = 0 density = 0 dielectric_constant = 0 oil_temp = 0 Rp = 0 status_code = 0 if message.dlc == 8: data_0 = '{0:x}'.format(message.data[0]).zfill(2) data_1 = '{0:x}'.format(message.data[1]).zfill(2) data_2 = '{0:x}'.format(message.data[2]).zfill(2) data_3 = '{0:x}'.format(message.data[3]).zfill(2) data_4 = '{0:x}'.format(message.data[4]).zfill(2) data_5 = '{0:x}'.format(message.data[5]).zfill(2) if message.arbitration_id == float.fromhex('1CFD083F'): viscosity = int(data_1 + data_0, 16) * 0.015625 density = int(data_3 + data_2, 16) * 0.00003052 dielectric_constant = int(data_5 + data_4, 16) * 0.00012207 elif message.arbitration_id == float.fromhex('18FEEE3F'): oil_temp = (int(data_3 + data_2, 16) * 0.03125) - 273.0 elif message.arbitration_id == float.fromhex('18FF313F'): status_code = int('{0:x}'.format(message.data[0]), 16) elif message.arbitration_id == float.fromhex('18FFFF3F'): Rp = (int(data_3 + data_2 + data_1 + data_0, 16) * 1000.0) + 100000 else: self.log_message.emit( "incorrect arbitration id transmitted") else: self.log_message.emit("Incorrect number of channels received") for i in range(message.dlc): data += '{0:x}'.format(message.data[i]) if (self.AIEnabled == 1): try: volts = TINK.getADC(0, 1) except: volts = 0.0 self.log_message.emit("retry daq data") i = 0 while volts == 0.0: try: volts = TINK.getADC(0, 1) self.log_message.emit("retry daq data") except: volts = 0.0 i += 1 if i == 10: self.log_message.emit("couldn't grab daq data") break rh_percent = (volts - 2.0) / 0.08 """ volts = TINK.getADC(0,2) outstr = outstr+', '+ str(volts) volts = TINK.getADC(0,3) outstr = outstr+', '+ str(volts) volts = TINK.getADC(0,4) outstr = outstr+', '+ str(volts) """ if (self.AIEnabled == 1): data += ("%11.6f,%10.8f,%10.8f,%10.5f,%0d,%0d,%6.3f" % (viscosity, density, dielectric_constant, oil_temp, status_code, Rp, rh_percent)) else: data += ("%11.6f,%10.8f,%10.8f,%10.5f,%0d,%0d" % (viscosity, density, dielectric_constant, oil_temp, status_code, Rp)) if status_code != 0: self.log_message.emit("sensor reports error code %d" % (status_code)) outstr = c + data self.count += 1 try: if status_code != 0 or message.arbitration_id == 486344767 or message.arbitration_id == 419360319 or message.arbitration_id == 419430207: print(outstr, file=self.outfile) # Save data to file self.log_message.emit(outstr) self.log_values.emit(data) except: self.log_message.emit("Canbus RX Thread Error")
import piplates.TINKERplate as TINK import time tripTEMP = 78 #this is the temperature we will operate around hysteresis = 1 #we will add a small amount of hysteresis to avoid chatter threshold = tripTEMP - hysteresis #the on/off threshold is the tripTEMP +/- the hysteresis fanON = True #initialize flag and.. TINK.relayON(0, 1) #turn on fan TINK.setDEFAULTS(0) #set all Digital I/O ports to their default states TINK.setMODE(0, 1, 'temp') #set the mode of Digital I/O port 1 to temperature while (True): #start loop temp = TINK.getTEMP(0, 1) #collect temperature data if (fanON): if (temp < threshold): #if on and temp is below threshold: fanON = False #clear state TINK.relayOFF(0, 1) #turn off fan threshold = tripTEMP + hysteresis #set high threshold else: if (temp > threshold): #if off and temp is above threshold: fanON = True #set state true TINK.relayON(0, 1) #turn on fan threshold = tripTEMP - hysteresis #set low threshold print("Temperature:", temp, ", Fan State:", fanON) time.sleep(1) #sleep 1 sec then
import piplates.TINKERplate as TINK import time stringW = [0xFF,0xFF,0xFF] #Create a single full white LED pattern stringB = [0x0,0x0,0x0] #Create a single full off LED pattern TINK.setDEFAULTS(0) #set all Digital I/O ports to their default states TINK.setMODE(0,1,'rgbled') #set the mode of Digital I/O port 1 to RGB LED while(True): #start repeating loop ain=TINK.getADC(0,3) #read the voltage on Analog Input channel 3 k=(ain-0.3)/3.7 #subtract a 0.3V offset and scale result if(k<0): k=0 #clip lower limit to 0 if(k>1): k=1 #clip upper limit to 1 j=int(k*8.0+0.5) nlString=[] #Create empty list for i in range(j): nlString=nlString+stringW #populate 1st part of list with white LEDs for i in range(8-j): nlString=nlString+stringB #populate rest of list with OFF LEDs #print(j,nlString) #debug statement - uncomment to use #print(ain) #debug statement - uncomment to use TINK.setRGBSTRING(0,1,nlString) #send eight LED values to port 1 time.sleep(0.1) #sleep 100msec before repeating
import piplates.TINKERplate as TINK #import TINKERplate module import math #import math module - needed for sine and pi import time #import the time module - needed for sleep Mag=10 N=360 mColor=(255,255,0) #this tuple represents the color yellow TINK.openMETER(4) #create a panel meter with the default of a single line TINK.setCOLOR(mColor) #set meter color TINK.setTITLE('Trigonometery Functions') #Set meter title while(True): #Loop forever for i in range(N): #do this 360 times TINK.setMETER(i,'degrees','Angle:',1) #write angle to line 1 val=math.sin(2*math.pi*i/360) #calculate sine of angle TINK.setMETER(val,'','Sine:',2) #write sine value to line 2 val=math.cos(2*math.pi*i/360) #calculate cosine of angle TINK.setMETER(val,'','Cosine:',3) #write cosine value to line 3 val=math.tan(2*math.pi*i/360) #calculate tangent of angle TINK.setMETER(val,'','Tangent:',4) #write tangent value to line 4 time.sleep(0.1)
import piplates.TINKERplate as TINK import time TINK.openMETER(1) #Create a display meter on the screen while (True): pot = TINK.getADC(0, 4) TINK.setMETER(pot, 'Level', 'Water:') time.sleep(.5)
def relay1Change(): #Callback function for Relay 1 if(rly1Cntl.value=='CLOSE'): TINK.relayOFF(0,1) else: TINK.relayON(0,1)
import piplates.TINKERplate as TINK import time TINK.openMETER(1) #Create a display meter on the screen while(True): pot=TINK.getPOT(0,4) TINK.setMETER(pot, ' ','Water Level:') time.sleep(.5)
def relay2Change(): #Callback function for Relay 2 if(rly1Cnt2.value=='CLOSE'): TINK.relayOFF(0,2) else: TINK.relayON(0,2)
def ledChange(): #Callback function for on board LED if(ledCntl.value=='ON'): TINK.setLED(0,0) else: TINK.clrLED(0,0)
import piplates.TINKERplate as TINK #load TINKERplate module import time #load time functions d = '\u00b0' TINK.setDEFAULTS(0) #set all digital channel to defaults. TINK.setMODE(0,1,'temp') #Set channel 1 to read a temperature sensor time.sleep(1) #wait 1 second for stabilization TINK.openMETER() #Create a display meter on the screen TINK.setTITLE('My Thermometer') while(True): temp=TINK.getTEMP(0,1) TINK.setMETER(temp,d+'F','Channel 1:') time.sleep(1)
def pwm5Change(): #Callback function for pwm output 5 val=int(dpwm5.value) TINK.setPWM(0,5,val)
import piplates.TINKERplate as TINK import time TINK.setDEFAULTS(0) #return all ports to their default states TINK.setMODE(0,8,'servo') #set Digital I/O port 1 to drive a servo lLimit=12.0 #The lower limit = 0 volts hLimit=166.0 #The upper limit = 12 volts while(True): analogIn=TINK.getADC(0,1) #read analog channel 1 #scale the data to an angle in the range of lLimit to hLimit angle=analogIn*(hLimit-lLimit)/12.0 TINK.setSERVO(0,8,lLimit+angle) #set servo angle time.sleep(.1) #delay and repeat
import piplates.TINKERplate as TINK import time #create battery state thresholds VL = 1.2 VH = 1.4 TINK.openMETER(1) #Create a panel meter on the screen #Change window title: TINK.setTITLE("TINKERplate Battery Tester") #TINK.setCOLOR((255,0,0)) #start with red text while (True): bat = TINK.getADC(0, 1) #read analog chanel 1 if (bat >= VH): TINK.setCOLOR((0, 255, 0)) #show green text TINK.setMETER(bat, 'Volts', 'GOOD', 1) #indicate a GOOD battery if ((bat >= VL) and (bat < VH)): TINK.setCOLOR((255, 255, 0)) #show yellow text TINK.setMETER(bat, 'Volts', 'OK', 1) #indicate an OK battery if (bat < VL): TINK.setCOLOR((255, 0, 0)) #show red text TINK.setMETER(bat, 'Volts', 'BAD', 1) #indicate a BAD battery time.sleep(.5) #delay and repeat