Memory Block and SPIDataRW - 24 bits in, 10 bits out


Does anyone know how to simultaneously send 24 bits (no interuptions) and receive 10 bits? I am connecting a MCP3008 analog-to-digital chip to read a voltage and here is a very good article on this subject MCP3008 Article.

The SPIDataRW requires a 24 uninterupted bits at 1 MHz going in, and a 10-bit response back from the MCP3008 (MCP3008 Datasheet).

The three sent bytes are &h01 (tells MCP3008 to initialize for data transfer), a second byte of &h80 to select the operating mode and read from Channel 0, and &h00 as the last empty bits to be retrieved. Here is my code:

[code] Listbox1.ColumnCount = 2
Listbox1.HasHeading = True

Const MyPotentiometer = 0
Const SPICLK = 11
Const SPIMISO = 9
Const SPIMOSI = 10
Const CE0 = 8

//set the pin to MyPotentiometer and the frequency to 1 MHz
If (GPIO.SPISetup(MyPotentiometer, 1000000) <0) then
Label2.Text = “SPI Setup failed”
Label2.Text = “SPI Setup successful”
End If


//Get the SPI initialized to transfer data
Dim m as New MemoryBlock(3)
m.byte(0)= &h01 //start bit
//1 for single ended, 0 for differential
m.byte(1)= &h80 //bits to select operating mode and a three bit channel number (0)
m.byte(2)= &h00

Dim Result as Integer
Result = GPIO.SPIDataRW(MyPotentiometer, m.CString(0), 8)
Listbox1.AddRow("Result = ", CStr(Result))
Result = GPIO.SPIDataRW(MyPotentiometer, m.CString(1), 8)
Listbox1.AddRow("Result = ", CStr(Result))
Result = GPIO.SPIDataRW(MyPotentiometer, m.CString(2), 8)
Listbox1.AddRow("Result = ", CStr(Result))[/code]

Using three SPIDataRW calls creates a space in the fast 1MHz signal. The results are 8, 8, and -1. The 10 received bits are the result of the voltage, meaning 1024 is the maximum reference voltage and 0 is the minimum reference voltage - but bytes are sent as 8-bits at a time.

The MCP3008 performs successful operational functions from the shell, so everything is wired correctly.

Do you have any helpful suggestions? Thanks.

I can see something wrong here: you should write your entire memory block in one operation:

Result = GPIO.SPIDataRW(MyPotentiometer, m, 3)

with the 3 being the number of bytes. This is in line with the “usage” comment in the GPIO module:

// Usage:
// Dim ok As Integer = GPIO.SPIDataRW(channel, mm, mm.Size)
// where mm is a memory block 

That being said, I’m having problems with this myself. I get back precisely the same 3 bytes which I send. No change.

Did you ever get it working?


Hello Richard,

Yes, there are many ways to get the data. Here is working Example 20-1 from my Raspberry Pi Electronics book:



In the meantime I found the problem, by looking at the wiringPi source code. It turns out that the Declare in the GPIO module is wrong. The 2nd parameter needs to be a pointer, not a CString. With that change, it works perfectly.