Julian Rogers Home Anemometer 2

Under Construction

# meter.py

# class to show a gauge or panel meter

# written by Roger Woollett


from sys import version_info

if version_info[0] < 3:

    import Tkinter as tk

    import tkFont as tkf

else:

    import tkinter as tk

    import tkinter.font as tkf

    

import math


class Meter(tk.Canvas):

    def __init__(self,master,*args,**kwargs):

        tk.Canvas.__init__(self,master,*args,**kwargs)

        

        self.layoutparams()

        self.graphics()

        self.createhand()

        

        self.setrange()

        

    def layoutparams(self):

        # set parameters that control the layout

        height = int(self['height'])

        width = int(self['width'])

        

        # find a square that fits in the window

        if(height*2 > width):

            side = width

        else:

            side = height*2

        

        # set axis for hand

        self.centrex = side/2

        self.centrey = side/2

        

        # standard with of lines

        self.linewidth = 2

        

        # outer radius for dial

        self.radius = int(0.40*float(side))

        

        # set width of bezel

        self.bezel = self.radius/15

        self.bezelcolour1 = '#c0c0c0'

        self.bezelcolour2 = '#808080'

    

        # set lengths of ticks and hand

        self.majortick = self.radius/8

        self.minortick = self.majortick/2

        self.handlen = self.radius - self.majortick - self.bezel - 1

        self.blobrad = self.handlen/6

             

    def graphics(self):

        # create the static components

        self.create_oval(self.centrex-self.radius

        ,self.centrey-self.radius

        ,self.centrex+self.radius

        ,self.centrey+self.radius

        ,width = self.bezel

        ,outline = self.bezelcolour2)

        

        self.create_oval(self.centrex-self.radius - self.bezel

        ,self.centrey-self.radius - self.bezel

        ,self.centrex+self.radius + self.bezel

        ,self.centrey+self.radius + self.bezel

        ,width = self.bezel

        ,outline = self.bezelcolour1)

        

        for deg in range(-60,241,6):

            self.createtick(deg,self.minortick)

        for deg in range(-60,241,30):

            self.createtick(deg,self.majortick)

        

    def createhand(self):

        # create text display

        self.textid = self.create_text(self.centrex

        ,self.centrey - 3*self.blobrad

        ,fill = 'red'

        ,font = tkf.Font(size = -int(2*self.majortick)))

        

        

        # create moving and changeable bits

        self.handid = self.create_line(self.centrex,self.centrey

        ,self.centrex - self.handlen,self.centrey

        ,width = 2*self.linewidth

        ,fill = 'red')

        

        self.blobid = self.create_oval(self.centrex - self.blobrad

        ,self.centrey - self.blobrad

        ,self.centrex + self.blobrad

        ,self.centrey + self.blobrad

        ,outline = 'black', fill = 'black')

        

    def createtick(self,angle,length):

        # helper function to create one tick

        rad = math.radians(angle)

        cos = math.cos(rad)

        sin = math.sin(rad)

        radius = self.radius - self.bezel

        self.create_line(self.centrex - radius*cos

        ,self.centrey - radius*sin

        ,self.centrex - (radius - length)*cos

        ,self.centrey - (radius - length)*sin

        ,width = self.linewidth)

        

    def setrange(self,start = 0, end=100):

        self.start = start

        self.range = end - start

        

    def set(self,value):

        # call this to set the hand

        # convert value to range 0,100

        deg = 300*(value - self.start)/self.range - 240

        

        self.itemconfigure(self.textid,text = str(value))

        rad = math.radians(deg)

        # reposition hand

        self.coords(self.handid,self.centrex,self.centrey

        ,self.centrex+self.handlen*math.cos(rad), self.centrey+self.handlen*math.sin(rad))

        

    def blob(self,colour):

        # call this to change the colour of the blob

        self.itemconfigure(self.blobid,fill = colour,outline = colour)


This Class, written by Roger Wollett (who has done all the really smart work!), brings the dial into being. It should be saved in the same folder as the code calling it.

# myMeter2

# 11.11.18

# uses meter/gauge class written by Roger Woollett

from tkinter import *

from meter import *

from serial import *


import serial.tools.list_ports

#hopefully active port listed first!

ports = list(serial.tools.list_ports.comports())

#takes the first 12 characters

serialPort = str(ports[0])[0:12]

baudRate = 9600

ser = Serial(serialPort , baudRate, timeout=0, writeTimeout=0) #ensure non-blocking


# create the root window

root = Tk()

root.geometry("200x200")

root.title("WIND")


# create a frame

app = Frame(root)

app.grid()


meter = Meter(app, width = 200)

meter.setrange(start=0, end = 100)

meter.set(0)

meter.pack()


def task():

    val = ser.readline().decode('ascii')

    

    if len(val) != 0:

        #print(int(val))

        meter.set(int(val))

        

    root.after(10, task)


root.after(10, task)

root.mainloop()


Anemometer 3

The screenshot left shows the dial gauge running on a Raspberry Pi. The program to enable this is shown below.

The program reads a value from serial (the USB connection between the Feather and the Rpi). This is simply fed into the meter class.

Incidentally, this screenshot is from an Rpi with the “Official” Rpi 7” touch screen. I find that to get enough text on the screen to do useful work (as well as see enough of the Arduino IDE option screens) I have to change the screen resolution by editing config.txt.

Sudo nano /boot/config.txt

Then change framebuffer_width to 1024

And framebuffer_height to 614.

F3 to save, F2 to exit then sudo reboot.