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.

Everything Else » LV-MaxSonar-EZ4 height measurement

March 02, 2011
by abd445
abd445's Avatar

Hello, I am trying to use a height sensor to measure distances but its not working as its supposed to. So I built my circuit based on the temperature sensor project included in the nerdkit guide and instead of the temperature sensor I connected the LV-MaxSonar-EZ4 using its analog pin out. I used the same code as the tempsense and changed the conversion factor as voltage to inches using 1in./9.67 mV (given in the datasheet for EZ4) The problem that I am encountering is that the distance is always approximately 1.5 to 2 inches off the actual distance.

Could anybody please help me? Any input is appreciated. I can answer any questions you might have regarding my project.

Thanks! Adi

March 02, 2011
by abd445
abd445's Avatar

Also could anybody explain to me, what does the height sensor with 1 inch resolution mean?

March 02, 2011
by Noter
Noter's Avatar

1 inch resolution means the smallest increment it can measure is 1 inch thus all your measurements will be in whole inches with no fractional values. Maybe all you need is to calibrate by adding/subtracting 1 or 2 inches worth from the value you read from the ADC pin. Devices aren't always perfect and often a little tweak in the software is all that's needed.

March 13, 2011
by abd445
abd445's Avatar

Thanks for the reply, it was really helpful.

I have another question regarding my project. The EZ-4 height sensor is always on when the circuit is powered and I was wondering if there is a way to tell it when to measure and when to be idle so that it doesn't keep draining power. Does anybody has any ideas how to implement it? Just to make it more clear, I want it to operate just like a weight scale does, i.e, it powers up when a person steps on it otherwise it is turned off.

Thanks!

March 13, 2011
by Ralphxyz
Ralphxyz's Avatar

So what is a EZ-4 height sensor?

The only google results are this thread and Design Review.

If you are measuring people's height won't you need more than a 1" resolution?

I'd like to see the specsheet on the EZ-4.

Very interesting paper.

Ralph

March 17, 2011
by abd445
abd445's Avatar

Well EZ-4 is a ultrasonic distance measurement device. The design review that you found is our project and we have an EZ-4 with 1cm resolution instead of the 1" one.

Here is the specsheet: http://www.sparkfun.com/datasheets/Sensors/Proximity/XL-EZ4-Datasheet.pdf

Also, I tried using the code for the temperature sensor with some modifications, but for some reason the distance is off by 2 to 4 inches and it is not a constant. Could you think of anything that i might be doing wrong? If you want I can post the code that I use too. thanks!

March 17, 2011
by Ralphxyz
Ralphxyz's Avatar

Make sure you have stable Vcc and ADC reference, you could even use a separate power supply for ADC reference (with a common ground).

Also you might try some of the other reading methods possible using serial. You could easily send the serial readout to a PC to confirm the variable readings.

Yes please post your code.

Is your code stable with no sensor but Vcc and then Gnd to pin 23 (or whichever pin you are using)?

How about with the tempsensor in place how is that?

This is very interesting, I liked the XL- MaxSonar®- EZ4 that would be fun to experiment with.

Ralph

April 04, 2011
by abd445
abd445's Avatar

Hello Ralph,

Attached below is the code that I used. I trying to combine the height measurement with a weight scale reading as well taking help from the weight scale project proposed at nerd kits, but instead of using python i am using C and I want to display the weight on the LCD that I got from nerd kits instead of the LCD of the weight scale. I tried this code but I am unable to display the weight. It just displays a constant number 01 and it doesn't change no matter how much pressure I put on the scale.

Also the temperature sensor worked fine when I tried it.

Any help is appreciated.

Thanks! Adi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// seniordesign.c
// using NerdKits with ATmega168
// ****taken from example temperature sensor code 
//     and changed to apply to distance sensor EZ-4
//     and then added weight scale to project *******
 
#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 -- height sensor analog input
// PC1 -- weight scale analog in
//
// PB4 - bridge excite
// PB3 - 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 conversion started
  ADCSRA |= (1<<ADSC);
 
  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;
}
 
double sampleToInches(uint16_t sample) {
  // conversion ratio in INCHES/STEP:
  // (5000 mV / 1024 steps) * (1 cm / 4.8828125 mV) * (0.3937 in / 1 cm)
  //       ^^^^^^^^^^^              ^^^^^^^^^^              ^^^^^^
  //        from ADC                 from EZ4          in/cm conversion
  return (sample * (4937.5 / 1024.0 / 4.8828125 * 0.3937)); 
}
 
int main() {
  // start up the LCD
  lcd_init();
  FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
  lcd_home();
 
  // set PB3, PB4 as outputs
  DDRD |= (1<<PB3) | (1<<PB4);
 
  // start up the Analog to Digital Converter
  adc_init();
 
  // start up the serial port
  uart_init();
  FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
  stdin = stdout = &uart_stream;
 
  // holder variables for distance data
  uint16_t last_sample = 0;
  double this_dist;
  double dist_avg;
  int8_t rounded;
  uint8_t i;
 
  // holder variables for weight scale
  int16_t reading;
 
  while(1) {
    // ***********************DISTANCE SENSOR PART*********************
    // take 100 samples and average them!
    ADMUX = 0;
    dist_avg = 0.0;
    for(i=0; i<100; i++) {
      last_sample = adc_read();
      this_dist = sampleToInches(last_sample);
 
      // add this contribution to the average
      dist_avg = dist_avg + this_dist/100.0;
      rounded = dist_avg;
    }
 
    // *************************WEIGHT SCALE PART**********************
    ADMUX = 1;
 
    // set polarity +-
    PORTD |= (1<<PB3);
    PORTD &= ~(1<<PB4);
    // wait 5 time constants (bw=12kHz, T=13.2us)
    delay_us(66);
    // take reading
    reading = adc_read();
    //printf_P(PSTR("%d "), adc_read());
 
    // set polarity -+
    PORTD |= (1<<PB4);
    PORTD &= ~(1<<PB3);
    // 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);
 
    // write message to LCD
    lcd_home();
    lcd_write_string(PSTR("ADC: "));
    lcd_write_int16(last_sample);
    lcd_write_string(PSTR(" of 1024   "));
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Distance: %.2f"), dist_avg);
    lcd_write_string(PSTR("in.     "));
 
    lcd_line_three();
    lcd_write_string(PSTR("Weight: "));
    lcd_write_int16(reading);
 
    // write message to serial port
    //printf_P(PSTR("%.2f degrees F\r\n"), dist_avg);
  }
 
  return 0;
}
April 04, 2011
by Ralphxyz
Ralphxyz's Avatar

I think I remember a similar occurrence, I'll try to go through your code and reload my code code to see if we can get you moving on.

Ralph

April 06, 2011
by abd445
abd445's Avatar

OK thanks! Looking forward to your reply!

April 11, 2011
by abd445
abd445's Avatar

Hey Ralph,

I was just wondering if you've had the chance to look through the code yet? I tried debugging it, so I removed the height sensor (EZ-4) and just hooked up the mcu to a weight scale, but I could not figure out the problem. Could you please help me with this? I am trying to get the weight from the strain gauge sensor on a weight scale and display the weight on an external LCD through mcu.

Thanks!

Post a Reply

Please log in to post a reply.

Did you know that interrupts can be used to trigger pieces of code when events happen? Learn more...