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.

Support Forum » Weighscale project

August 29, 2010
by Ralphxyz
Ralphxyz's Avatar

I have the weighscale project compiled and running on my Nerdkit.

I finally have Python installed and I am running the weighscale_pc-weighScale.py code.

This is what I get without any weight on the scale:

Weighscale

Why all of the meaningless activity when there is no weight on the scale?

Then if i do put weight on the scale the scale is so huge that nothing is represented. I mean it is looking for 20,000,000,000 to 120,000,000,000 cans.

Is this just to be expected and if I want any thing usable I just need to roll my own?

I actually do not need the pc connection and python as everything I need to display will be on the LCD but the LCD only shows 271 no matter what I do just a static 271 no scrolling.

I modified the weighscale C program to add the LCD output.

    // weighscale.c
    // for NerdKits with ATmega168
    // mrobbins@mit.edu

    #define F_CPU 14745600

    #include <stdio.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"

    // PIN DEFINITIONS:
    // PC0 -- analog in
    //
    // PD4 - bridge excite
    // PD3 - bridge excite

    void adc_init() {
      // set analog to digital converter
      // for external reference (5v), single ended input ADC0
      ADMUX = 0;

      // set analog to digital converter
      // to be enabled, with a clock prescale of 1/128
      // so that the ADC clock runs at 115.2kHz.
      ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

      // fire a conversion just to get the ADC warmed up
      ADCSRA |= (1<<ADSC);
    }

    uint16_t adc_read() {
      // set ADSC bit to get the *next* conversion started
      ADCSRA |= (1<<ADSC);

      // read from ADC, waiting for conversion to finish
      // wait for it to be cleared
      while(ADCSRA & (1<<ADSC)) {
        // do nothing... just hold your breath.
      }
      // bit is cleared, so we have a result.

      // read from the ADCL/ADCH registers, and combine the result
      // Note: ADCL must be read first (datasheet pp. 259)
      uint16_t result = ADCL;
      uint16_t temp = ADCH;
      result = result + (temp<<8);

      return result;
    }

    int main() {

      // start up the LCD
      lcd_init();
      FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
      lcd_home();

      // set PD3, PD4 as outputs
      DDRD |= (1<<PD3) | (1<<PD4);

      // init ADC
      adc_init();

      // init serial port
      uart_init();
      FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
      stdin = stdout = &uart_stream;

      int16_t reading;
      while(1) {
        // set polarity +-
        PORTD |= (1<<PD3);
        PORTD &= ~(1<<PD4);
        // wait 5 time constants (bw=12kHz, T=13.2us)
        delay_us(66);
        // take reading
        //reading = adc_read();
        printf_P(PSTR("%d "), adc_read());
        lcd_line_two();
        fprintf_P(&lcd_stream, PSTR("Reading: %d"), adc_read);
        // set polarity -+
        PORTD |= (1<<PD4);
        PORTD &= ~(1<<PD3);
        // wait 5 time constants (bw=12kHz, T=13.2us)
        delay_us(66);
        // take reading
        //reading = reading - adc_read();
        printf_P(PSTR("%d\r\n"), adc_read());

        // send over serial port
        //printf_P(PSTR("%d\r\n"), reading);
      }

      return 0;
    }

How would I get a active reading on the LCD?

Thanks again as always for the much needed help.

Ralph

August 29, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Ralph,

It looks like the version on our site has a few comments we had in there for demo purposes. The code you have prints out both values before and after we flip the polarity of the wheatstone bridge. Comment out your current printf statements, and uncomment the ones that currently read the adc. You will notice that the ADC is read before and after we switch the polarity of the excite wires. Then print out the value of the reading variable only at the end. I think you will find that reading makes more sense.

Humberto

August 30, 2010
by Ralphxyz
Ralphxyz's Avatar

Thanks Humberto, that makes sense. I knew there was some logic to what was happening.

Ralph

August 30, 2010
by Ralphxyz
Ralphxyz's Avatar

I made the changes suggested by Humberto, now I am getting recursion overflow error on line 21 of weighscale_pc-weighScale.py.

Strange that it technically worked before the changes without any recursion errors but now after making the suggested changes I get this error.

Here is the modified section of weighscale.c. I didn't touch anything else, honest.

  while(1) {
    // set polarity +-
    PORTD |= (1<<PD3);
    PORTD &= ~(1<<PD4);
    // wait 5 time constants (bw=12kHz, T=13.2us)
    delay_us(66);
    // take reading
    reading = adc_read();

    /*printf_P(PSTR("%d "), adc_read());
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Reading: %d"), adc_read);*/

    // set polarity -+
    PORTD |= (1<<PD4);
    PORTD &= ~(1<<PD3);
    // wait 5 time constants (bw=12kHz, T=13.2us)
    delay_us(66);
    // take reading
    reading = reading - adc_read();
    //printf_P(PSTR("%d\r\n"), adc_read());

    // send over serial port
    printf_P(PSTR("%d\r\n"), reading);
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Reading: %d"), reading);
  }

With the changes the LCD "appears" to be reading correctly or at least I am getting a reading.

I hadn't planned on doing any PC output at this time but now that I have python almost working I am intrigued and would like to get this working.

Ralph

August 30, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Ralph,

That's pretty strange. Is this error message coming from the python script? Could you post the error message you are getting, as well as the python script you are using.

Humberto

August 31, 2010
by Ralphxyz
Ralphxyz's Avatar

Here is the recursion depth error, using the modified python script to send output to the LCD (which works).

  File "weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "weighscale_pc-weighScale.py", line 21, in getReading
    x = s.readline()
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 232, in read
    buf = ctypes.create_string_buffer(size)
  File "C:\Python27\lib\ctypes\__init__.py", line 57, in create_string_buffer
    if isinstance(init, (str, unicode)):
RuntimeError: maximum recursion depth exceeded while calling a Python object

The graph is completely empty. I get a couple of hundred line 24 error messages.

Ralph

August 31, 2010
by Ralphxyz
Ralphxyz's Avatar

Now here is a more detailed look at the error.

I have tried to slow down the display stream using some averaging and delays.

The error:

Measuring zero...
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Exception RuntimeError: RuntimeError('cannot join current thread',) in <module 'threading' from 'C:\Python27\lib\threading.pyc'> ignored
Error in sys.excepthook:
TypeError: 'NoneType' object is not callable

Original exception was:
Traceback (most recent call last):
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 145, in <module>
    ZERO = averageReadings(1000)
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 36, in averageReadings
    sum += getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading
    return getReading()
  File "C:\Nerdkits\Code\WeighScale\weighscale_pc-weighScale.py", line 24, in getReading

Ralph

August 31, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Ralph,

I think I actually gave you incorrect advice before. I went back and read through the PC side code, and the subtraction is actually happening on the python side. You should revert back to the old way the code was. Notice that it reads the number, switches the polarity, then sends the next reading before sending the newline character. This is what the python code reads, then splits the line at the space, subtracts the two numbers, and interprets the result.

I apologize that I did not see that earlier. The reason you are getting the error now is that before the code used to send two values per line, now it is only sending one, and it is causing an error on the python end. We wrote the code so that it would try again if there was an error in a reading. So it was just trying over and over until it busted the stack. That still doesn't really explain why you were getting such crazy results before. I suggest you revert to using the pc-pygame.py code, that one does not try to convert the result into number of cans.

The issue might be that you need did not change the ZERO and SLOPE variables in the code. You need to figure out what these values are for your particular setup. We figured out the slope for our scale putting a known mass on the scale and you are basically looking for the increase in ADC values per pound.

Humberto

August 31, 2010
by Ralphxyz
Ralphxyz's Avatar

Thanks Humberto, I as wondering about the ZERO and SLOPE variables as I remember Mike mentioning them in the Weighscale Tutorial. I thought I might need to adjust them.

Ralph

Post a Reply

Please log in to post a reply.

Did you know that first-order systems have a exponentially decaying response to step inputs? Learn more...