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

December 01, 2010
by bdubb427
bdubb427's Avatar

I would love to see if this code works too. I am currently having problems running my pygame.py and weighscale.py. Python hasn't been very kind to me so I want to see if I can get an active reading on the LCD as well. I tried using your code Ralph and the LCD only displays "Reading: 2217". Any help on this would be appreciated!!! Thanks

Bryan

December 02, 2010
by Ralphxyz
Ralphxyz's Avatar

Ok, good you are getting a reading.

"Reading: 2217" is coming from Line 87: fprintf_P(&lcd_stream, PSTR("Reading: %d"), adc_read);

Try fprintf_P(&lcd_stream, PSTR("Yup it works: %d"), adc_read); to make sure.

Now analyze the code to see what 2217 means. Possible you need to divide adc_read by a thousand or one hundred, or not.

What are you weighing?

I also had a tough time with python, I did get it to work but it was not easy.

Ralph

December 02, 2010
by Ralphxyz
Ralphxyz's Avatar

Here is my last working code:

#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"

// 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);  //done above allready

  // 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;
}

// tempsensor has the sampleToFahrenheit code here

int main() {

  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);   // pin 5 & 6

  // 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());
    // write message to LCD
    lcd_home();
    lcd_write_string(PSTR("Reading: "));
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("%d"), adc_read());
        // set polarity -+
    PORTD |= (1<<PD4);
    PORTD &= ~(1<<PD3);
    // wait 5 time constants (bw=12kHz, T=13.2us)
    delay_us(66);
        printf_P(PSTR("%d\r\n"), adc_read());
        lcd_line_three();
        fprintf_P(&lcd_stream, PSTR("%d"), adc_read());
  }

  return 0;
}

I have not looked at this for three months but I believe it was working.

I do not know if there is anything specific about my strain gauge setup so it might not be generic.

Ralph

December 08, 2010
by bdubb427
bdubb427's Avatar

Hey Ralph, bare with me please because I am very knew to this, and I am what you would call a "noobie". I've been trying to get my weighscale project to work for severals weeks now, and still have been unsuccessful. I gave up on using python with all the errors I had with it, so stumbling across your post I wanted to try to get the LCD to display an active reading just through the weighscale.C code.

Trying your code I get a reading that says Reading: (on line 1), 483 (on line 2), than again 483 (on line 3). I am unsure of what this actually means because my ACTUAL weighscale has not been connected to the MCU/Amplifier. I have not connected it because even after soldering the 4 wires on my digital weighscale, I do not know which ones are sense and excite :( I can randomly plug them in to see if they change the reading on the LCD, but so far no luck. Here's a picture of the wires, can you tell me what you think?

alt image text

There are four wires coming out from the back of the weighscale, Light Blue, Yellow, Black and Red. I have to assume for now that Black and Red are the Excite wires going out to the MCU, and the Light blue and Yellow wires are the "sense" wires that go into the amplifier.

Please help me or correct me if am I wrong about this! I've been struggling to get my LCD to display the reading of the weighscale!

December 08, 2010
by Ralphxyz
Ralphxyz's Avatar

Because I do not know what I am doing, I therefore do not know what I should not do, so I would try it (others might scream at the thought, but hey it works for me)!

I liked your drawing in your other thread. I would "assume" red and black are excite and blue and yellow are your sense wires.

You really need to have a multimeter, you will find that you are always are coming up with needing one as you build circuits so treat yourself to a Christmas gift, no matter your religion.

I would test your op-amp output without anything connected to have a base line to start.

Ralph

April 24, 2011
by abd445
abd445's Avatar

Hey,

I tried to display the weight on the LCD but it is really "jumpy", as in the reading from the ADC varies a lot. Even if the scale is off, it jumps around a lot, I am not using python code, just trying to display the raw ADC voltage on the LCD. Does your values flicker too?

April 25, 2011
by Ralphxyz
Ralphxyz's Avatar

Hi abd445, if I remember correctly yes it was jumpy.

Are you using the Nerdkit tempsensor code for ADC capture?

Or actually if you are using something similar using a averaging scheme maybe you could change the data type and use a thousand samples instead of 100. Or do a average of the average of the average and display that.

And/or if you are in a loop assign a value from the ADC to a new variable then break the loop and display the new variable.

There probable are ways of reducing the sensitivity of the op-amp also.

It's to bad the timing of your asking about the strain gauge project is off by two months.

I was going to revive working on my strain gage project late spring or summer so then I would have a working device at hand to better help you.

Your project probable is approaching a deadline for completion.

How is the whole project doing. I really liked the outline of what you were trying to do.

Ralph

May 03, 2011
by Ralphxyz
Ralphxyz's Avatar

Hey abd445 I do not know if you were following my thread on jumpy ADC readout but bretm posted some sudo code that might solve the problem.

I have not tested it yet.

Ralph

May 05, 2011
by Ralphxyz
Ralphxyz's Avatar

abd445 and others looking to slow the ADC sample rate down I published my working code (bretm's modifications) and Noter publish an over sampling codesample that should also do the trick.

Ralph

May 05, 2011
by BobaMosfet
BobaMosfet's Avatar

What is the circuit in the above picture? I see a blob-chip, and some other chips, but the pic is a bit hazy, so I can't read the writing on the chips or smb parts.

If the sensor has a number, perhaps I can find a datasheet.

BM

Post a Reply

Please log in to post a reply.

Did you know that a motor is harder to turn when its terminals are shorted together? Learn more...