Issue with daisychaining MCP3008 SPI on Raspberry Pi with Python - python

At the moment I am trying to let two MCP3008's communicate through SPI with my raspberry pi and a Python script. A potentiometer should send a certain analog value to the MCP3008 input channel.
Here is my setup in Fritzing:
Breadboard Schematic
and here is the schematic overview:
Schematic Overview
The SPI wiring is based upon a standard daisychain schematic as shown in:
SPI Daisy Chain
The Python Code I am using is:
import spidev
import time
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 1000000
def read_spi(channel):
spidata = spi.xfer2([0,(8+channel)<<4,0])
return ((spidata[1] & 3) << 8) + spidata[2]
try:
while True:
channeldata = read_spi(0)
print (channeldata)
time.sleep(.1)
except KeyboardInterrupt:
spi.close()
I am getting values, but they fluctuate a lot with every value possible between 0 and 1023.
I've tried it with one MCP3008 without daisychaining of course and it worked fine, so my guess is that it has something to do with either the daisychain being incorrect, or the addressing of the MCP3008.
Can you guys help me out? Thanks alot!!
Cheers,
Devatu

Might be a late response, but according to the data sheet this chip can't be daisy-chained at all.
I am also looking for an ADC which can be daisy-chained.

Related

Arduino pyfirmata analog reading problems

I am having some problems reading analog values from my Arduino Mega using pyfirmata.
I use Arduino Mega with a Mega Sensor Shield.
I would like to read analog values from a HW-201 IR sensor (pin A5).
I have uploaded the Standard firmata sketch on Arduino IDE, and I am running the following code using Anaconda Spyder:
import serial
import serial.tools.list_ports
from pyfirmata import ArduinoMega, util
from time import sleep
def readArduinoPort():
COM = []
ports = list(serial.tools.list_ports.comports())
for p in ports:
if "Arduino" in p.description:
COM.append(str(p.device))
return COM
COM = readArduinoPort()
board = ArduinoMega(COM[0])
pin = board.get_pin('a:5:i')
it = util.Iterator(board)
it.start()
try:
while True:
print(pin.read())
sleep(0.1)
except KeyboardInterrupt:
pass
Now, this code runs just fine the first time I use it, generating numbers close to 1 when the sensor is detecting proximity and numbers close to 0 when not detecting anything.
However, whenever I try to run the Iterator a second time (without restarting the kernel), the code generates seemingly random numbers (almost like the pin was floating, like nothing was connected to it).
Any idea why this is happening? Is this a normal behavior?
Thank you!
I already checked these questions that do not entirely address my issue:
arduino pyfirmata analog reading
Analog readings on Arduino returns wrong values
I have the same result by not having anything pinned to pin A5 of the Arduino Mega.
I wasn't sure, but I tried adding:
board.analog[5].enable_reporting()
before the iterator and then:
board.analog[5].disable_reporting()
but nothing changed.
Board Differences
I ran into the same problem. I own both a Mega and an Uno and needed to select the appropriate Board and Processor in the tools menu:
Tools > Board > _board_
Tools > Processor > _processor_

Problem reading RS485 communication packets with raspberry pi using python

I'm having trouble reading packets over a serial line, in the modbus protocol. I want to read the temperature from my thermometer that uses RS485 communication, so I used raspberry pi in combination with waveshare rs485 can hat.
Here is a code sample.
#!/usr/bin/python3
import RPi.GPIO as GPIO
import serial
import time
from prectime import processor_sleep
rsp = 4
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(rsp, GPIO.OUT)
GPIO.output(rsp, 0)
a = float(7.5)
command = [0x02,0x04,0x00,0x05,0x00,0x01,0x21,0xF8]
r = str(0)
ser = serial.Serial('/dev/ttyS0', 9600, timeout = 0.1)
while len(str(r)) < 31:
GPIO.output(rsp, 1)
ser.write(command)
processor_sleep(a)
GPIO.output(rsp, 0)
r = ser.readline()
print(r,' --- ',a)
a = a + 0.1
processor_sleep(1000)
ser.close()
My prectime library with the processorsleep () function is here.
import time
def processor_sleep(ms):
_ = time.perf_counter() + ms/1000
while time.perf_counter() < _:
pass
As soon as I connect the sniffer in parallel to the line I can see that the initiating packet is received and answered by the sensor correctly, however, when I try to read the same answer via python the result is this:
b'' --- 7.5
b'' --- 7.6
b'' --- 7.699999999999999
b'\x02\x04\x02\x01S\xbc\x9d' --- 7.799999999999999
b'\x02\x04\x02\x01S\xbc\x9d' --- 7.899999999999999
b'\x02\x04\x02\x01S\xbc\x9d' --- 7.999999999999998
b'\x02\x04\x02\x01S\xbc\x9d' --- 8.099999999999998
and it should look like (from sniffer)
b'\x02\x04\x02\x01\x52\xbc\x9d'
I don't know what's going on, sometimes it happens that I catch the packet well, but it's rare.
Thanks in advance.
This topic has been already discussed at length.
Just go here and follow the rabbit hole of links in my answer. You should be able to solve your problem.
I would go for the libmodbus solution (there is a Python wrapper too) but you can also stay with pymodbus if you want.
Anyway, what sawdust says in the comments is also very good advice. The easiest would be to invest 10 bucks and buy a transceiver that is able to toggle itself. Yours is not, unfortunately.

Controlling RGB-Matrix via SPI (Python)

The Raspberry Pi has a Broadcom BCM 2835 chip allowing it to interface with SPI devices on its GPIO pins. I encountered a problem adressing LEDs in a 8x8 Matrix via SPI.
I want to adress single LEDs on the matrix, but I haven't figured out, which bytes adresses which LED(s).
SPIdev seems to be the right library for this purpose und I stumbled upon this snippet of code:
import spidev
import time
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 7629
# Split an integer input into a two byte array to send via SPI
def write_pot(input):
msb = input >> 8
lsb = input & 0xFF
spi.xfer([msb, lsb])
# Repeatedly switch a MCP4151 digital pot off then on
while True:
write_pot(0x1FF)
time.sleep(0.5)
write_pot(0x00)
time.sleep(0.5)
Does anyone know which values adresses (a) specific LED(s)?
In C/C++ adressing works very well via the wiringpi-library, a useful documentation can be found here:
http://wiki.52pi.com/index.php/RPI-RGB-LED-Matrix_SKU:EP-0075

Raspberry Pi MAX31856 Thermocouple Temperature Reading Error

I'm working with t-type thermocouple and needs to read the temperature data using python on Raspberry Pi 3. I used Adafruit MAX31856 to connect the thermocouple to the Pi and and tried to read it using this module.
I want to read the temperature for an extended period of time so I tried to print it out in a while loop However, anytime I run my code, I only get few 'correct' readings then the temperature resets to 0 until I re-run the code again - see the attached image.
I don't know what is causing this, and I don't think this is a connection problem since it prints the correct temperature when I re-run the code without touching the set-up.
Does anyone know why the reading is resetting to 0?
Here is my code:
from Adafruit_MAX31856 import MAX31856
import time
# Raspberry Pi software SPI configuration.
CLK = 4
CS = 22
DO = 17
DI = 27
sensor = MAX31856(clk=CLK, cs=CS, do=DO, di=DI)
while True:
temp = sensor.readTempC()
print('Thermocouple Temperature: {0:0.3F}*C'.format(temp))
time.sleep(1.0)
Try resetting sensor by putting sensor = MAX31856(clk=CLK, cs=CS, do=DO, di=DI) in the while loop.

arduino read in pyfirmata gives output as none

I wrote a basic code for reading values from analog pin 0(I have a light sensor attached to it and the output is coming at analog pin 0) in python3 using pyfirmata, but it is giving the output as none no matter what. I tried the same code in arduino IDE and that is giving the right answer. Please help.
Code is :
from pyfirmata import Arduino, util
import time
board = Arduino('/dev/cu.usbmodem1411')
it = util.Iterator(board)
it.start()
board.analog[0].enable_reporting()
while True :
print (board.analog[0].read())
time.sleep(1)
Even when it gives an output after few seconds, it gives 0.29 which isn't actually the sensor value that comes on serial monitor. That value varies between 0 and 1023 and is relatively quite larger than this.
The analog pins of Arduino linearly translate the input voltages between 0 and +5V to 0
and 1023. However, in pyFirmata , the values between 0 and +5V are linearly translated
into the float values of 0 and 1.0. For example, if the voltage at the analog pin is 1V, an
Arduino program will measure a value somewhere around 204, but you will receive the
float value as 0.2 while using pyFirmata’s read() method in Python.
You'll need to start an Iterator thread before reading
board = pyfirmata.Arduino("COM5") # change com port
board.digital[3].mode = pyfirmata.INPUT
it = pyfirmata.util.Iterator(board)
it.start()
board.digital[3].read()
Most of the time it work, but sometimes None still show up. Sometimes time.sleep can help.
You have to do an if conditional first, something like this (and try running analogfirmata):
while True:
if board.analog[0].read() == None:
pass
else:
print("board.analog[0].read()")

Categories

Resources