Displaying ADC output on LCD problem

JayAuckland

New Member
Hi, am very new to this but...

I am trying to display the position of a 10k slider pot (between the 0 and 5v rails) by storing the 08M2 ADC value as a variable then feeding that value to a serial input AXE033 display. Eventually I hope to feed that ADC level down a serial bus to several 'slave' 08M2 chips so they can react to the level of the pot in various ways.

Code:
setfreq m4
pause 1000
serout c.0,N2400,(254,1)
pause 30

One:
readadc 4,b1
serout C.0,N2400,(254,128)
serout c.0,n2400,("Fader level:    ")
serout c.0,n2400,(254,192,)
serout c.0,n2400,(#b1)
pwmout 2,63,b1
goto One
As I slide the pot from bottom (0v) to top (5v) the LCD counts up from 000 - 255 just fine. But when moving back down it becomes erratic, showing values as high as 900... and as the displayed number descends down past 100 it jumps back to 900 and counts down in hundreds. From that point on it remains erratic regardless of whether the pot is moving up or down or what position it is at. And it never reads 000 at the bottom of the pot again... giving instead numbers in the double digit range.

An LED on the pwm out always shows a smooth transition from full off to full on and back down etc. regardless of the antics of the LCD

Can anyone tell me why I'm getting the erratic LCD readout?

(And by the way, why does the PWM dim the LED best when the period is set at 63 rather than 255 as I would have thought???)

Jay
 

Goeytex

Senior Member
Hi Jay,

I think this one has bitten most of us at least once.

The problem is that when decrementing, the previously written characters are retained on the display screen.

The code below show one way of addressing that.

Code:
setfreq m4
pause 1000
serout c.0,N2400,(254,1)
pause 30
pwmout 2,63,0    'Start PWM with a duty of 0

One:
    readadc 4,b1
    serout C.0,N2400,(254,128)
    serout c.0,n2400,("Fader level:    ")
    serout c.0,n2400,(254,192)
    serout c.0,n2400,(#b1,"   ") 'Added Spaces to clear previous characters 
 
    pwmduty 2, b1   'Use PWMDUTY here  

goto One
And by the way, why does the PWM dim the LED best when the period is set at 63 rather than 255 as I would have thought???
When the PWM gets too slow the LED will flicker. With PWM, a period value of 255 is slower than
a value of 63. As the period increases the speed ( frequency) decreases.

And rather than reinitalising PWM inside the loop, it is generally a better practice to use PWMDUTY inside the loop to change the PWM duty
 
Last edited:

hippy

Technical Support
Staff member
And by the way, why does the PWM dim the LED best when the period is set at 63 rather than 255 as I would have thought???
When using PWMOUT to control a LED, full brightness will be when the duty is four times the period, when period is a quarter of maximum duty.

Because you are using 'b0' to control brightness, 0 to 255, the period required to achieve maximum brightness needs to be 255/4 = 63.

With a period of 255, when 'b0' is at its maximum of 255, the PWMOUT will only be 25%.
 

JayAuckland

New Member
That's so excellent, thank you both! Probably would never ever have figured out the need to clear the previous characters!

And the advice about how to set up the PWM better is much appreciated, as is the explanation of the period and duty cycle thing (though that one I will have to make a cuppa and think thru a bit).

Thanks guys!

Jay
 

JayAuckland

New Member
Am back with something new that's stumping me(!).

I'm wanting to familiarise myself with how to write data into an eeprom and read it back again and use it.
Eventually I want to be able to "record" a constantly changing variable for a short period then "play" the data back.
As a first experiment I've connected my first ever eeprom (24LC256) to a 14m2 and am trying to write an adc input from a potentiometer) into the eeprom then read it back out and display the value through pwm to an led.

Here's my code (sorry I've forgotten how to include it in a code box):

setfreq m4
hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte
PwmOut C.2, 60, 0 'start with mimic led pwm duty at 0
Test:
readadc C.4, b0 'read pot adc into PIC variable b0
hi2cout 5, (b0) 'write PIC variable b0 value to eeprom byte 5
pause 10
hi2cin 5, (b1) 'read eeprom byte 5 into PIC variable b1
pwmduty C.2, b1 'apply PIC variable b1 value to pwm
goto test

When I run this the LED is constantly full on and does not track with the potentiometer as I had hoped. I remember reading somewhere that if there is an addressing problem writing to eeproms a default value of 255 is substituted - so maybe that is significant here.

When I modify the code with the i2c/eeprom-related lines removed from the code the led tracks the potentiometer just fine so it doesn't seem to be a 14M2 hardware/wiring problem.

Can anyone cast an eye over this please and give me a brainy nudge in the right direction?

Also, I see variously hi2cout-type commands and write12c-type commands used... which type of these commands should I be using?

Jay
 

lbenson

Senior Member
Do you have 4K7 pullups on your I2C data and clock lines?

Note that if you write to eeprom every 10 microseconds (approximately), you will quickly wear out your eeprom.

You may want to change the duty cycle (and save to eeprom) only if there is a change in your pot reading, and because of dithering, you might want to change only if you have a reading change greater than what you observe the dithering to be.

If you comment out your hi2cout lines and insert "b1= b0" before your pwmduty command, does it behave as you wish?

How many changes do you wish to record? On the 14M2, you have ram bytes 28-511 above the named variables which you could use without fear of writing too many times. You can access those with @bptr and peek/poke. (with @bptr, beware of exceeding 511--you will wrap and overwrite b0-b27).

Enclose your code with [ code] and [ /code] tags (without the space after "[") to put it in a code box.
 
Last edited:

JayAuckland

New Member
Thanks Ibenson,

I can't believe I neglected to do something as basic as put the pullup resistors on the lines!!! Duh! Too much thinking about code and not enough about the basics! More duh! Will put them on in the morning NZT and run it again. Fingers crossed that gets it going!

Thanks for highlighting the duty cycle etc. aspect. This bit of test code was just to make sure I could actually get PIC to eeprom communication going. The record cycle will not be used often, mostly it will be in replay mode and even then it will be only occasionally used. However I was in the back of my mind looking to ensure that i run the write cycle as slowly as possible to still give an acceptable output - which will eventually be to a servo. I suspect that even at a very slow cycle rate the 14M2 ram will not be big enough. To pause while the pot is inactive will mean adding a time factor to the saved data so there might be a trade-off between the length of time the eeprom can cover and the room needed for the extra data. But I will do some sums and keep the overall # of cycles in mind!

The peek and poke aspect is perhaps a bit beyond my knowledge and abilities at the moment - a quick read about it a few months ago scared the pants off me - but if I have to go there I will.

Thanks again,

Jay
 

Rick100

Senior Member
Am back with something new that's stumping me(!).

I'm wanting to familiarise myself with how to write data into an eeprom and read it back again and use it.
Eventually I want to be able to "record" a constantly changing variable for a short period then "play" the data back.
As a first experiment I've connected my first ever eeprom (24LC256) to a 14m2 and am trying to write an adc input from a potentiometer) into the eeprom then read it back out and display the value through pwm to an led.

Here's my code (sorry I've forgotten how to include it in a code box):

setfreq m4
hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte
PwmOut C.2, 60, 0 'start with mimic led pwm duty at 0
Test:
readadc C.4, b0 'read pot adc into PIC variable b0
hi2cout 5, (b0) 'write PIC variable b0 value to eeprom byte 5
pause 10
hi2cin 5, (b1) 'read eeprom byte 5 into PIC variable b1
pwmduty C.2, b1 'apply PIC variable b1 value to pwm
goto test

When I run this the LED is constantly full on and does not track with the potentiometer as I had hoped. I remember reading somewhere that if there is an addressing problem writing to eeproms a default value of 255 is substituted - so maybe that is significant here.

When I modify the code with the i2c/eeprom-related lines removed from the code the led tracks the potentiometer just fine so it doesn't seem to be a 14M2 hardware/wiring problem.

Can anyone cast an eye over this please and give me a brainy nudge in the right direction?

Also, I see variously hi2cout-type commands and write12c-type commands used... which type of these commands should I be using?

Jay
Hello Jay,

I think you need to change 'hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte' to 'hi2csetup i2cmaster, %10100000, i2cslow, i2cword' since your 24LC256 eeprom has 32,768 memory locations.

Near the bottom of the page
http://www.picaxe.com/BASIC-Commands/Advanced-IO-Interfacing/hi2csetup/
the devices are listed with the proper speed and address size for the setup command. The i2cslow will still work.

Good luck,
Rick
 

lbenson

Senior Member
Note that in your test code, the 10mS pause for the eeprom write to be accomplished probably takes up most of the time in your loop. That means that by not writing only when there is a non-dithering change in the pot reading (the pot changed by your fingers is on a human time scale), you will write to the eeprom about 100 times a second. I don't know what the 24LC256 write life is, but it would only take 1000 seconds of this to exceed the recommended limit for picaxe eeprom.

So it would be best to add a little bit of code to write only when the value is changed, and perhaps only when the value is changed by more than 1.

I realize that you are probably going to be writing sequentially through the 24LC256, so that gives you a lot more scope--but you may still wish to write only significant changes.
 
Top