jbentham / streaming

ADC data streaming for the Raspberry Pi
34 stars 4 forks source link

Adapting code for MCP3208 #2

Open noeldum opened 3 years ago

noeldum commented 3 years ago

I have been attempting to modify the code and get it to run with the MCP3208.

I have modified both transmission and receiving request like this below.

// ADC sample size (2 bytes, with 11 data bits)
#define ADC_RAW_LEN     3

...

// Definitions for 2 bytes per ADC sample (11-bit)
//#define ADC_REQUEST(c)  {0xc0 | (c)<<5, 0x00}
#define ADC_REQUEST(c)  {0x60 | (c)<<2, 0x00, 0x00}
#define ADC_VOLTAGE(n)  (((n) * 4.096) / 4096.0)
#define ADC_MILLIVOLTS(n) ((int)((((n) * 3300) + 1024) / 2048))
//Yp#define ADC_RAW_VAL(d)  (((uint16_t)(d)<<8 | (uint16_t)(d)>>8) & 0x7ff)
#define ADC_RAW_VAL(d)  (((uint16_t)(d)>>4) & 0xfff)

I also modified line 515 line below as I prefer seeing raw adc values rather than voltage.

                   //slen += sprintf(&vals[slen], "%s%4.3f", slen ? "," : "",
                        //ADC_VOLTAGE(ADC_RAW_VAL(rx_buff[i])));
                    slen += sprintf(&vals[slen], "%s%d", slen ? "," : "",
                        ADC_RAW_VAL(rx_buff[i]));

After compilation it does run well and produce the following without any options.

pi@raspberrypi:~/streaming-main $ sudo ./rpi_adc_stream 
RPi ADC streamer v0.20
VC mem handle 6, phys 0xbebc4000, virt 0xb6fcc000
SPI frequency 1000000 Hz
ADC value 2063 = 2.063V
Closing

The 2063 value is clearly expected and matches with other methods I have used to read the adc.

Now the issue seems to be when I start the streaming as the raw value I get in this instance is 15. For example below

pi@raspberrypi:~/streaming-main $ sudo ./rpi_adc_stream -n 1
RPi ADC streamer v0.20
VC mem handle 6, phys 0xbebc4000, virt 0xb6f03000
Reading 1 samples at 100 S/s
15
Closing
Total samples 1, overruns 0

I must have missed some part of the code to modify but that is not too obvious to me at that point.

WOuld you be able to guide me in the right direction?

jbentham commented 3 years ago

Afraid I don't have the time to look at this in detail, but your first step should be to display the hex data you're getting back from the ADC. Also, I don't understand why you are transmitting 0x60 | (c) << 2, if you look at the data sheet, the first bit (0x80) is 'start', so you are delaying the start until the second bit, which will shift the response data 1 bit right, reducing the resolution from 10 to 9 bits (assuming you are doing 16-bit reads) - you have nothing to gain by doing that. I would have thought you'd transmit 0xc0 | (c) <<3

On 27/11/2020 17:33, noeldum wrote:

I have been attempting to modify the code and get it to run with the MCP3208.

I have modified both transmission and receiving request like this below.

|// ADC sample size (2 bytes, with 11 data bits) #define ADC_RAW_LEN 3 // Definitions for 2 bytes per ADC sample (11-bit) //#define ADC_REQUEST(c) {0xc0 | (c)<<5, 0x00} #define ADC_REQUEST(c) {0x60 | (c)<<2, 0x00, 0x00} #define ADC_VOLTAGE(n) (((n) * 4.096) / 4096.0)

define ADC_MILLIVOLTS(n) ((int)((((n) * 3300) + 1024) / 2048))

//Yp#define ADC_RAW_VAL(d) (((uint16_t)(d)<<8 | (uint16_t)(d)>>8) & 0x7ff) #define ADC_RAW_VAL(d) (((uint16_t)(d)>>4) & 0xfff) |

I also modified line 515 line below as I prefer seeing raw adc values rather than voltage.

|//slen += sprintf(&vals[slen], "%s%4.3f", slen ? "," : "", //ADC_VOLTAGE(ADC_RAW_VAL(rx_buff[i]))); slen += sprintf(&vals[slen], "%s%d", slen ? "," : "", ADC_RAW_VAL(rx_buff[i])); |

After compilation it does run well and produce the following without any options.

|pi@raspberrypi:~/streaming-main $ sudo ./rpi_adc_stream RPi ADC streamer v0.20 VC mem handle 6, phys 0xbebc4000, virt 0xb6fcc000 SPI frequency 1000000 Hz ADC value 2063 = 2.063V Closing |

The 2063 value is clearly expected and matches with other methods I have used to read the adc.

Now the issue seems to be when I start the streaming as the raw value I get in this instance is 15. For example below

|pi@raspberrypi:~/streaming-main $ sudo ./rpi_adc_stream -n 1 RPi ADC streamer v0.20 VC mem handle 6, phys 0xbebc4000, virt 0xb6f03000 Reading 1 samples at 100 S/s 15 Closing Total samples 1, overruns 0 |

I must have missed some part of the code to modify but that is not too obvious to me at that point.

WOuld you be able to guide me in the right direction?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/jbentham/streaming/issues/2, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACNUSEWOIO2CLQ2HNXGHYVDSR7PFXANCNFSM4UFE7CZA.

noeldum commented 3 years ago

In order to read the full 12 bits I modified

define ADC_RAW_LEN 2

to

define ADC_RAW_LEN 3

(mcp3208 is 12bits) As the mcp3208 uses 5 bit command we must use a 24 bit transfer. I guess there are many ways one could do this as only 17bits over the 24 are relevant. That part is working well and does not concern me that much.

Thank you for the suggestion with the hex output. I'll try and investigate this way.

chandu07 commented 3 years ago

Hello @noeldum, have you been able to run it with MCP3208? any help or hint on sort of the modifications you made to the code will be very much helpful.

Nice work @jbentham!

noeldum commented 3 years ago

Hi Chandu, I got somewhat close to get it working but not to completion yet. Time for me to dive into this again. If you make some progress yourself just let me know as well.

noeldum commented 3 years ago

@chandu07 I gave up as I could not get anywhere. However I have been much more successful using Pigpio. It also uses dma. https://github.com/joan2937/pigpio

There is an example for MCP3202 that I am adapting for mcp3208. Nearly there. I can share if someone need it.

chandu07 commented 3 years ago

@chandu07 I gave up as I could not get anywhere. However I have been much more successful using Pigpio. It also uses dma. https://github.com/joan2937/pigpio

There is an example for MCP3202 that I am adapting for mcp3208. Nearly there. I can share if someone need it.

Hey Noeldum, we were able to figure it out with Pigpio example. it was kinda simple, just had to change the number of bits and the exact bits we were reading accordingly and vola it works.

Thanks for the effort though, will share the changes we made in the repo for Pigpio may be.