NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Meat thermometer project Live Graph to Display Points over a Larger time period

August 16, 2011
by kemil
kemil's Avatar

Hi all,

I've been playing around with the meat thermometer project (specifically the python side of things). I want to be able to make the live graph show a longer time period. At the momenta data point streams on and leaves the GUI after about 20 seconds (i would like it to be about 10 mins), ive been playing with this code for a while now and ive found it pretty hard to make it do what i want. I think its because the data is assigned to a pixel number so a 600 pixel wide screen can only show the last 600 pieces of data. I guess the simplest thing to do would be to take the average of the last say 100 pixels and assign that to one pixel.......but i dont know how to do this if anyone has and ideas on how to go about increasing the time range and the accompanying python code i would be very thankful.

Thanks kemil

August 16, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Kemil,

Ultimately you are definitely going to have to average over a large time period if you want to get more data onto the screen. The live scale graph program already does that, I think you will just want to adjust how many samples it averages over. I would suggest looking over the FeederThread class, specifically the getReading() and averageReading() functions.

Humberto

August 17, 2011
by kemil
kemil's Avatar

Hi Humberto, thanks for the help. I tried implementing the averageReadings() function into my Feeder.Thread class as follows:

class FeederThread(threading.Thread): running = True addPoint = None average = 100

 def getReading(self):
   global ser
   x = ser.readline()
   k = x.split()
   if len(k)<3:#if len(k)<5:
     print "yuck, got", x
     return self.getReading()

   try:
     return (float(k[0]),float(k[1]),float(k[2]))

   except ValueError: #valueError is right type but inappropriate value 
     print "yuck, got ", x
     print len(k)
     return self.getReading()

 def averageReadings(self, average):
   sum = 0.0
   for i in xrange(average):
     sum += self.getReading()
   return sum / average

 def run(self):
   global ser
   #self.s = serial.Serial("COM4", 115200)
   ser.readline()

   while self.running:
     k = self.averageReadings(self.average)

     if self.addPoint:
       self.addPoint(k)

But i get the following error: TypeError: unsupported operand types(s) for +=: 'float' and 'tuple'

this error is referring to the line:

sum += self.getReading()

so i changed this line to:

sum += int(self.getReading())

but i got then error: TypeError: int() argument must be a string or a number, not 'tuple'

I initially though it was because in my c code im using

printf_P(PSTR("%.2f %.2f %.2f \r\n")

whilst in the weight scale code you're using

printf_P(PSTR("%d\r\n")

but when i use %d py python code doesnt work Any thoughts on what i should do.... im thinking of only sending over ADC values and doing the manipulation of them on the python side of things which would make my source code similar to the weightscale code which obviously works...

Thanks

Kemil

August 17, 2011
by kemil
kemil's Avatar

been playing with the code for a while and as far as i can gather the problem is that i can not transfer the technique used in averageReadings() which in the python code for weightscale only has one input.... but i have three which means the function run() in the Feeder thread class is no working. So How do i made the averageReading() function average all three inputs?

kemil

August 17, 2011
by bretm
bretm's Avatar

Since it returns three values, you need three sums. Something like

sum0 = 0.0
sum1 = 0.0
sum2 = 0.0

for i in xrange(average):
   r = self.getReading()
   sum0 += r[0]
   sum1 += r[1]
   sum2 += r[2]
August 18, 2011
by kemil
kemil's Avatar

Hi bretm, Thanks for your reply, the problem is that sum is an python function so i cant so what you said. However, i did something similar - I made three different averageReadings() functions like this:

def averageReadings1(self, average):

   sum = 0.0

   for i in xrange(average):
     r = self.getReading()
     sum += r[0] 
   return sum / average

 def averageReadings2(self, average):

   sum = 0.0

   for i in xrange(average):
     r = self.getReading()
     sum += r[1] 
   return sum / average

 def averageReadings3(self, average):

   sum = 0.0

   for i in xrange(average):
     r = self.getReading()
     sum += r[2] 
   return sum / average

and then i added this line to the run function in the python code from the weight scale turorial:

  k = self.averageReadings1(self.average)+self.averageReadings2(self.average)+...     
  self.averageReadings2(self.average)

which i though would put the three values into list form BUT now i get an error in the addPoint function (taken from python code for meat thermometer tutorial - because it handles multiple values send from MCU). the error says the line

self.history[i].append(q[i]) typeError 'float' object is unsubscriptable

Any Ideas on what i should do?

Thanks Kemil

August 18, 2011
by kemil
kemil's Avatar

Figured it out.... My mistake i just changed the line

k = self.averageReadings1(self.average)+self.averageReadings2(self.average)+...     
self.averageReadings2(self.average)

to

k = [self.averageReadings1(self.average),self.averageReadings2(self.average),...     
self.averageReadings3(self.average)]

And it works perfectly

kemil

Post a Reply

Please log in to post a reply.

Did you know that interrupts can cause problems if you're not careful about timing and memory access? Learn more...