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 » Corrupted Data

December 13, 2011
by kemil
kemil's Avatar

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()
December 13, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi kemil,

I believe you are running into wonkiness from the PySerial implementation on Windows. I think I remember running into it too at some point. The first thing I would try to do is run the print loop much slower. Give it a delay between each iteration of the while loop, the slower the better.

Humberto

Post a Reply

Please log in to post a reply.

Did you know that NerdKits make a great parent/child activity? Learn more...