MikroE AC Current Click on SPI
-
Hi, I've been having difficulty in reading data from the SPI protocol using the MikroE module found here: AC Current Click. So far I've read about other posts on reading SPI using MikroE modules like this one and have tried adapting that to the AC current module however having poor luck. My setup and code is shown below:
from machine import SPI from machine import Pin import machine spi_cs = Pin('P23',mode=Pin.OUT) spi_cs.value(True) spi = SPI(0, mode=SPI.MASTER, baudrate=1000000) while True: spi_cs.value(False) buf = bytearray(2) spi.readinto(buf) adc = (((buf[0] << 8) | buf[1]) >> 1) & 0xfff spi_cs.value(True) print(buf, adc)
I am using P23 as the chip select since I'll be need three of these sensors, so far I have just connected one. I've also considered using analog pins to do the task and have had success, but limited (working) pins are available. Thus I am set on using SPI for communication.
My output at the moment looks like so:
bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xf2\x00') 2304 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x0f\xff') 2047 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\xff\xff') 4095 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0 bytearray(b'\x00\x00') 0
Which doesn't seem correct.
Would greatly appreciate any code examples or hardware configurations require to achieve this objective! thanks.
-
Hi @jcaron ! Thanks for your reply.
@jcaron said in MikroE AC Current Click on SPI:
@Anthony-Leung Did you also connect ground together, and are you correctly powering the sensor with 3.3 V (along with the right jumper setting on the sensor)?
Yes, the mikroE is wired to 3V3 on both the FiPy and the AC current sensor. The jumper uses 3V3 as standard so yes the hardware is correctly wired.
You probably need a small delay between
/CS
going high and going back low. It needs to stay high for at least 625 ns (tCSH) for each sample, not sure if your current code keeps it high long enough.I've added a 1ms delay for the
/CS
based on your comment, seems to not make a difference thus far.You may want to try different combinations of
polarity
andphase
. The ADC chip on the sensor is supposed to work with both 0,0 (default forSPI
) and 1,1.Also have done this, no significant difference.
The ADC is a bit weird as it outputs 12 bits while SPI works on 8 bits. The ADC datasheet says it should still work by rearranging bits a bit like you're doing (though I'm not convinced by your shifts).
I've just read further into the data sheets and have adjusted it to the recommended bit shifts. I think it should now be correct following this description:
"The MCU receive register will contain the lowest-order seven bits and the B1 bit repeated as the A/D Converter has begun to shift out LSB first data with the extra clock. Typical procedure would then call for the lower-order byte of data to be shifted right by one bit to remove the extra B1 bit. The B7 bit is then transferred from the high-order byte to the lower-order byte, and then the higher-order byte is shifted one bit to the right as well"To which I have done:
data = ((buf[0] << 7) | (buf[1] >> 1)) & 0xfff
What are you measuring? Is the current you're measuring constant (and known) or variable? What value are you expecting?
So far I've been trying to get a consistent value under no current, meaning it is not reading from any source. My assumption is that I should have a fairly consistent value with error however I am simply getting huge spikes in results. In my new segment of code I've measured the analog reading of the current as well to compare.
from machine import SPI from machine import Pin import machine import time # Analog pin settings adc = machine.ADC() apin = adc.channel(pin='P13') val = apin() # SPI settings spi_cs = Pin('P23',mode=Pin.OUT) spi_cs.value(True) spi = SPI(0, mode=SPI.MASTER, baudrate=10000, bits=16, firstbit=SPI.MSB) buf = bytearray(2) while True: spi_cs.value(False) # select the pin time.sleep_ms(1) # wait spi.readinto(buf) # read data = ((buf[0] << 7) | (buf[1] >> 1)) & 0xfff # concatenate bytes and rearrange as per specs val = apin() # retrieve analog output print( "bits: ", "{0:16b}".format(data), "\t spi: ", "{:10.4f}".format(30*data/4096), "A", "\t analog: ", "{:10.4f}".format(30*val/4096), "A") spi_cs.value(True) # deselect pin time.sleep_ms(1) # wait
My results are:
bits: 0 spi: 0.0000 A analog: 1.1572 A bits: 0 spi: 0.0000 A analog: 1.1353 A bits: 111111111111 spi: 29.9927 A analog: 0.9448 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.1646 A bits: 1110111111 spi: 7.0239 A analog: 1.0547 A bits: 0 spi: 0.0000 A analog: 1.1133 A bits: 111111111100 spi: 29.9707 A analog: 1.0620 A bits: 111111111111 spi: 29.9927 A analog: 1.1279 A bits: 111111111111 spi: 29.9927 A analog: 1.2817 A bits: 111111111111 spi: 29.9927 A analog: 1.1206 A bits: 0 spi: 0.0000 A analog: 1.2744 A bits: 0 spi: 0.0000 A analog: 1.2378 A bits: 111111111111 spi: 29.9927 A analog: 1.1646 A bits: 111111111111 spi: 29.9927 A analog: 1.1938 A bits: 111111111111 spi: 29.9927 A analog: 1.1353 A bits: 0 spi: 0.0000 A analog: 1.1353 A bits: 0 spi: 0.0000 A analog: 1.1646 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.0840 A bits: 111111111111 spi: 29.9927 A analog: 0.9595 A bits: 0 spi: 0.0000 A analog: 0.9155 A bits: 0 spi: 0.0000 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 0.9448 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 0.9229 A bits: 0 spi: 0.0000 A analog: 1.0547 A bits: 0 spi: 0.0000 A analog: 1.0327 A bits: 111111110000 spi: 29.8828 A analog: 1.0107 A bits: 111111111111 spi: 29.9927 A analog: 1.1206 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111 spi: 3.7427 A analog: 1.0107 A bits: 0 spi: 0.0000 A analog: 1.0767 A bits: 111111111100 spi: 29.9707 A analog: 0.9595 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.0986 A bits: 0 spi: 0.0000 A analog: 1.0693 A bits: 0 spi: 0.0000 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.0181 A bits: 111111111111 spi: 29.9927 A analog: 1.0986 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 0 spi: 0.0000 A analog: 1.0767 A bits: 0 spi: 0.0000 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 0 spi: 0.0000 A analog: 1.1426 A bits: 0 spi: 0.0000 A analog: 1.1499 A bits: 111111111111 spi: 29.9927 A analog: 1.0840 A bits: 111111111111 spi: 29.9927 A analog: 1.2085 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 0 spi: 0.0000 A analog: 1.1206 A bits: 0 spi: 0.0000 A analog: 1.2012 A bits: 111111111111 spi: 29.9927 A analog: 1.0547 A bits: 111111111111 spi: 29.9927 A analog: 1.0986 A bits: 111111111111 spi: 29.9927 A analog: 1.0986 A bits: 0 spi: 0.0000 A analog: 1.1719 A bits: 0 spi: 0.0000 A analog: 1.0693 A bits: 111111111111 spi: 29.9927 A analog: 1.0767 A bits: 111111111111 spi: 29.9927 A analog: 1.1060 A bits: 111111111111 spi: 29.9927 A analog: 1.1938 A bits: 0 spi: 0.0000 A analog: 1.1865 A bits: 0 spi: 0.0000 A analog: 1.1865 A bits: 111111111111 spi: 29.9927 A analog: 1.0620 A bits: 111111111111 spi: 29.9927 A analog: 1.1572 A bits: 111111111111 spi: 29.9927 A analog: 1.1353 A bits: 111011111 spi: 3.5083 A analog: 1.1279 A
So as you can see in the
spi
column there is a lot of fluctuation compared to analog readings. How should I go about this?Thank you in advance again!
UPDATE
All good I have found the problem! I've connected the CLK and MISO pins in incorrectly.
-
@Anthony-Leung Did you also connect ground together, and are you correctly powering the sensor with 3.3 V (along with the right jumper setting on the sensor)?
You probably need a small delay between
/CS
going high and going back low. It needs to stay high for at least 625 ns (tCSH) for each sample, not sure if your current code keeps it high long enough.You may want to try different combinations of
polarity
andphase
. The ADC chip on the sensor is supposed to work with both 0,0 (default forSPI
) and 1,1.The ADC is a bit weird as it outputs 12 bits while SPI works on 8 bits. The ADC datasheet says it should still work by rearranging bits a bit like you're doing (though I'm not convinced by your shifts).
What are you measuring? Is the current you're measuring constant (and known) or variable? What value are you expecting?