|
|
View previous topic :: View next topic |
Author |
Message |
demedeiros
Joined: 27 Dec 2013 Posts: 71
|
MCP3208 Occasionally get odd data |
Posted: Tue Feb 21, 2023 10:43 am |
|
|
Hi All,
Have a system with a PIC24HJ256GP610 that is reading from a couple MCP3208 ADCs. It functions well for a while, and then the ADC starts to return weird data, for example, the ADC returned 0xE81F (59,423DEC) on one occasion. This seems to happen more and more as time goes on.
For now I have wrote a simple filtering function where if the returned value is greater than 4098 I ignore the value and use the previous value. This seems to work, but I would like to get to the root of the issue if possible. Code snippets below:
The erroneous data does seem to come directly from the analogReadSE function.
MCP3208 Read
Code: |
unsigned int16 analogReadSE(unsigned int16 CSPIN, unsigned int8 channel)
{
//Base address corresponds to 0b00000110 in which the two 1's denote the
//start bit and the single/differential bit. We default to 1 for single ended
unsigned int8 byte0 = 0x06;
char addressD2 = 0;
char addressD0D1 = 0;
//Ensure the top 5 bits are 0
channel = channel & 0x07;
addressD0D1 = channel & 0x03;
//If channel is greater than 3, then bit 0 of byte 0 is always 1
if(channel > 3)
{
byte0 = 0x07;
}
//Put the D0D1 bits in the MSb of byte 1
unsigned int8 byte1 = (addressD0D1 << 6) & 0xC0;
output_low(CSPIN);
delay_us(5);
spi_write(byte0);
//spi_write(byte1);
unsigned int8 highbyte = spi_read(byte1);
unsigned int8 lowbyte = spi_read(0x00);
output_high(CSPIN);
return (highbyte << 8) | lowbyte;
} |
Read Analog Data
Code: |
void readAnalogJoystick()
{
//Read left joystick analog inputs
leftAnalog.A0 = analogReadSE(leftADCCS, 0);
delay_ms(5);
leftAnalog.A1 = 4096-analogReadSE(leftADCCS, 1);
delay_ms(5);
leftAnalog.A2 = analogReadSE(leftADCCS, 2);
delay_ms(5);
//Read left joystick button inputs
leftAnalog.BUT1 = input(L_BUT1);
leftAnalog.BUT2 = input(L_BUT2);
leftAnalog.BUT3 = input(L_BUT3);
leftAnalog.BUT4 = input(L_BUT4);
leftAnalog.BUT5 = input(L_BUT5);
leftAnalog.BUT6 = input(L_BUT6);
delay_ms(10);
//Read right joystick analog inputs
rightAnalog.A0 = analogReadSE(rightADCCS, 0);
delay_ms(5);
rightAnalog.A1 = analogReadSE(rightADCCS, 1);
delay_ms(5);
rightAnalog.A2 = analogReadSE(rightADCCS, 2);
//Read right joystick button inputs
rightAnalog.BUT1 = input(R_BUT1);
rightAnalog.BUT2 = input(R_BUT2);
rightAnalog.BUT3 = input(R_BUT3);
rightAnalog.BUT4 = input(R_BUT4);
rightAnalog.BUT5 = input(R_BUT5);
rightAnalog.BUT6 = input(R_BUT6);
}
|
Header Setup
Code: |
#include <24HJ256GP610.h>
#device ICSP=1
#use delay(crystal=20000000)
#FUSES NOWDT,NOPROTECT,HS,NOIESO,NOPR,NOCKSFSM,NOWRT,NODEBUG
#use SPI(MASTER, SPI1, BAUD=500000, MODE=0, STREAM = SPI1)
#use i2c(master, I2C1)
#use rs232(UART1, baud = 57600, ERRORS, STREAM = HID)
#use rs232 (UART2, baud = 57600, ERRORS, STREAM = PC)
#use rs232(ICD, STREAM=DEBUG)
#include <stdint.h>
void InitJ1939Address(void);
void InitJ1939Name(void);
#define __CCS_USE_TIMER_PERIPH 1
#include <tick.c>
//Following Macros used to initialize unit's J1939 Address and Name - Required
#define J1939InitAddress() InitJ1939Address()
#define J1939InitName() InitJ1939Name()
//Following defines/macros used to associate your tick timer to J1939 tick timer
// defines/macro's - Required
#define J1939GetTick() TickGet()
#define J1939GetTickDifference(a,b) (a-b)
#define J1939_TICKS_PER_SECOND TICKS_PER_SECOND
#define J1939_TICK_TYPE TICK
//Include the J1939 driver
#include <j1939.c>
|
Any thoughts? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Tue Feb 21, 2023 10:57 am |
|
|
general comments, haven't read you actual code,line by line.....
Does it happen to ALL of the 8 channels of the ADC or just one, or two ?
Is the power supply rock steady stable and properly filtered ?
Are you sampling too fast ?
Can you use an oscilloscope to see the actual waveforms on VDD, grounds, ADC pins ?
Is Vref of the ADC steady ??
Getting accurate, repeatable 12bit results requires GREAT PCB layout, bypass filters,shielded cables, EMI protection...
digital is easy, analog can be 'fun' !
Jay |
|
|
demedeiros
Joined: 27 Dec 2013 Posts: 71
|
|
Posted: Tue Feb 21, 2023 11:57 am |
|
|
Thanks for the response.
It does seem to happen to all channels of the ADC. Also not specific to a single chip (I am using 2).
3.3V supply has about 60mVpp of noise on it
I don't think I'm sampling too fast, I have a 5ms delay between each read. Looks like the device can sample up to 100ksps at 5V.
VREF is steady, provided by an external precision reference, LM4132BMF-3.0.
I will probe the values with a scope to see if I can see any issues. The issue does seem to come along with increased run-time though...
For example, I sent the data to a PC via UART. I built a simple logging app to log the maximum values. Started it on Friday and it was ok, remoted in saturday morning and again was ok, with no weird values.
Came in today, and had a number of very large events as mentioned.
Thank you! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Tue Feb 21, 2023 12:00 pm |
|
|
Don't get me wrong, but it's not erroneous.
If you look, the values of the last 13bits are guaranteed (a null, and then
the 12 data bits), but all the bits before this show the Dout line as
Hi-Z You are only meant to take the last 12 or 13 bits. Values
of the bits before this mean nothing. If you want them to have a guaranteed
value, you would have to apply a tiny resistive pull-up or pull-down to
the line.
What is happening is the Vih/Vil of the chip is drifting with temperature,
resulting in high levels actually being seen.
You should be simply masking off the last 12 bits. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Tue Feb 21, 2023 12:10 pm |
|
|
Interesting... it was fine all weekend while YOU weren't there....hmmm...
As it appears to be all channels...
Look for 'silly' things, like cellphone near it, static problems, Other 'EMI' creators like motors,arc welders, Weller soldering stations, ???
Add a 'time stamp' to the data
from PIC..... time,ADC channel,rawdata,LF,CR
Use known test voltages ( A precision Vref and resistor ladder works great )
Getting analog to be 100% involves a lot of 'elimination' using the 'try this, see what happens'...... It's the 'can't happen, not according to the 'book' things ' that usually get you ! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Tue Feb 21, 2023 12:17 pm |
|
|
My guess would be something like LED lights, inducing noise on the Hi-Z
line when he is there.The bits are just garbage, and should not be used. |
|
|
demedeiros
Joined: 27 Dec 2013 Posts: 71
|
|
Posted: Tue Feb 21, 2023 12:50 pm |
|
|
Thanks for the insight guys.
Ttelmah, you are absolutely correct... If I take the erroneous 0xE81F and mask out the 12 good bits, I get 2079DEC which right where I should be for midrange!
You guys are great, right to the point, I really appreciate it!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Tue Feb 21, 2023 3:36 pm |
|
|
DOH ! I feel silly... I should have thought of that...
looked at the ADC datasheet
maybe IT doesn't care about the ???? bits, but the PIC sure does !!
just before this...
return (highbyte << 8) | lowbyte;
'zero' the highest nibble ( 4 bits). |
|
|
demedeiros
Joined: 27 Dec 2013 Posts: 71
|
|
Posted: Tue Feb 21, 2023 8:22 pm |
|
|
Thanks!
I ended up doing the following:
Code: |
return ((highbyte << 8) | lowbyte) & 0x0FFF);
|
That seems to be working well. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Tue Feb 21, 2023 9:26 pm |
|
|
It's great to hear you got an 'easy' digital SOLUTION cause analog can be 'fun' to figure out !
Worst or 'best' for me was one group of remote energy control units in a subsystem would go 'funny', ONLY on Sunday mornings,from 1 to 2 AM. Never any other time and updates were every 15 seconds.... It took 3 weeks to figure out it was 'crosstalk' on a BELL telephone 'span' cable. Had them flip the pair and trouble magically went away. Seems the crosstalk was a bank's secured phone line updating their computer, that line was ONLY used, yes, on Sunday's from 1 to 2 AM........ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed Feb 22, 2023 2:15 am |
|
|
Yes, I looked at the datasheet and realised in standard readout mode,
everything before the last 13bits (it does guarantee to include a null
13th bit), is '?'. The timing diagram shows the incoming line as Hi-Z
here.
It does suggest there is something in the room inducing a little noise,
when you are there, so you need to be careful that this doesn't introduce
anything into the genuine analog signal.... Caveat. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|