December 13, 2011
by kemil
|
Hi all,
I have a problem which ive never come across before and its really puzzling me!
all im doing is sending data to my pc using the usb cable. the code im using to send the data is:
#define F_CPU 14745600
#include <stdio.h>
#include <math.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"
int main (void)
{
uart_init();
FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar,...
_FDEV_SETUP_RW);
stdin = stdout = &uart_stream;
double hi;
hi = 150.0;
while(1)
{
printf_P(PSTR("%.2f %.2f\r\n"), hi, hi);
}
return 0;
}
As you can see its very simple. on the PC side im using some python code adapted from the pc-pygame.py file which comes with the meat thermometer tutorial.
so heres the problem, when the data is being sent after about 3 seconds of being streamd it starts getting corrupted. for example instead of looking like this
['150.00', '150.00']
['150.00', '150.00']
['150.00', '150.00']
['150.00', '150.00'] ...etc
it starts looking like this
['115000150.00', '10']
['1500.50.00', '150.00']
['1500', '.00','150.150.00', '150.00'].. etc
Basically different permutations of the number 150.00
I am pretty sure the problem is on the microcontroller side of things because if i burn something else onto the MCU which also prints something and i use the same python code the error goes away. BUT when i use PUTTY there doesnt seem to be a problem with the way the data is streamed which makea me doubt my first assumption.
ANY help would be hugely appreciated
kemil
here is the python code:
import threading
import time
import serial
import sys
import pygame
import pygame, pygame.font, pygame.event, pygame.draw, string
from pygame.locals import *
# FeederThread continuosly reads the data coming from the MCU
# Data from the MCU
class FeederThread(threading.Thread):
running = True
addPoint = None
def getReading(self):
global ser
x = ser.readline()
k = x.split()
print k
if len(k)<2:#if len(k)<5:
print "yuck, got", x
return self.getReading()
try:
return (float(k[0]),float(k[1]))
except ValueError: #valueError is right type but inappropriate value
print "yuck, got ", x
return self.getReading()
def run(self):
global ser
#self.s = serial.Serial("COM4", 115200)
ser.readline()
while self.running:
if self.addPoint:
self.addPoint(self.getReading())
class Plotter:
bgcolor = (255,255,255)
linecolors = (0,0,255)
linewidth = 3
textcolor = (0,0,0)
textsize = 10
numInputs = 2 #total number of inputs coming from the MCU
smallFontSize = 12
smallFontSize1 = 20
def handleEvents(self):
global clicked_in_c1_box
global clicked_in_c2_box
for event in pygame.event.get():
if event.type is pygame.QUIT:
self.feeder.running = False
sys.exit()
elif event.type is pygame.K_ESCAPE:
self.clearHistory()
elif event.type is pygame.KEYDOWN:
eventKey = event.key
self.process_character(eventKey)
elif event.type is pygame.MOUSEBUTTONDOWN:
self.handleMouseDown(pygame.mouse.get_pos())
def process_character(self,eventKey):
global current_string
global clicked_in_light_intensity_box
global ser
if clicked_in_light_intensity_box is True:
inkey = eventKey
if inkey == K_BACKSPACE:
current_string = current_string[0:-1]
elif inkey == K_MINUS:
current_string.append("_")
elif inkey <= 127:
current_string.append(chr(inkey))
if inkey == K_RETURN:
''.join(current_string[0:-1])
print ''.join(current_string)
add_a_b = 'b'
add_tag = ''.join(current_string)
ser.write(str(add_tag))
ser.write("\n")
print add_tag
current_string = []
clicked_in_light_intensity_box = False
def handleMouseDown(self, (x, y)):
global clicked_in_light_intensity_box
if x >= 175 and x<=240 and y>=20 and y<=40: #light intensity
print pygame.mouse.get_pos()
clicked_in_light_intensity_box = True
def clearHistory(self):
self.history = [ [0.0 for x in xrange(self.width)] for y in
xrange(self.numInputs) ]
def generatePoints(self):
history = self.history
return [[(i, self.verticalTransform(line[i])) for i in
xrange(len(line))] for line in history ]
def addPoint(self, q):
if self.history:
for i in range(self.numInputs):
self.history[i].pop(0)
self.history[i].append(q[i])
def __init__(self, feeder):
self.size = self.width, self.height = 500,300
self.feeder = feeder
self.clearHistory()
self.feeder.addPoint = self.addPoint
def verticalTransform(self, q):
return 300 - q #self.vzero - self.vscale * q
### Main init code
def main(self):
global ser
ser = serial.Serial("COM4", 115200)
global current_string
current_string = []
global clicked_in_light_intensity_box
clicked_in_light_intensity_box = []
# set up display
pygame.init()
pygame.font.init()
screen = pygame.display.set_mode(self.size)
# set up feeder
self.feeder.start()
background = pygame.Surface(self.size).convert_alpha()
background.fill(self.bgcolor)
font = pygame.font.SysFont("Verdana", self.textsize)
smallFont = pygame.font.SysFont("Verdana", self.smallFontSize)
smallFont1 = pygame.font.SysFont("Verdana", self.smallFontSize1)
k = 0
clicked_in_Home = True
clicked_in_ViewLiveGraph = False
while True:
screen.blit(background, (0,0))
pygame.draw.rect(screen, (10,10,200), (175,20,65,20), 0) #light 1
if clicked_in_light_intensity_box is True:
pygame.draw.rect(screen, (0,255,0), (175,20,65,20), 0)
text = smallFont.render(" Enter Light Intensity 1:", True,
self.textcolor)
textsize0 = font.size("Enter Light Intensity")
screen.blit(text, (0,18))
content = " pH: %.2f " % self.history[1][-1]
text = font.render(content, True, self.textcolor)
textsize0 = font.size(content)
screen.blit(text, (375,103))
text = font.render("%s" %''.join(current_string), True,
self.textcolor)
textsize0 = font.size(content)
screen.blit(text, (185,23))
content = "Temperature : %.2f degrees C" % self.history[0][-1]
text = font.render(content, True, self.textcolor)
textsize0 = font.size(content)
screen.blit(text, (10,100))
pygame.display.flip()
self.handleEvents()
if __name__ == "__main__":
feeder = FeederThread()
plotter = Plotter(feeder)
plotter.main()
|