Using DS2408 with Raspberry Pi GPIO 4 1wire linux driver - raspberry-pi

I have a Raspberry Pi B+ with the latest raspbian.
I activated 1wire support through interface options in raspi-config command and I connected my DS2408 chip on to the GPIO 4.
When I try to check for the list of devices, they all show up
ls -la /sys/bus/w1/devices/
when I try to cat their output or status I receive ?.
when I try to write on the output file, the nothing happens.
I have two questions:
Is there an easier software interface to communicate with the DS2408? There is a lot of documentation for reading temperature sensor data but DS2408 does not work like that.
I tried with a 1wire USB dongle and OWFS which works, but is there a possibility to make the GPIO 4 as the bus master for OWFS and communicate using the OWFS software interface?
answer to any one of these questions would solve my problem of talking to DS2408 connected to GPIO 4 of a RPI B+

Actually I have managed to operate DS2408 with Raspberry Pi 4 but I had really tough time getting it to work. First of all it had to be connected properly: RSTZ through 10k resistor to Vcc, I/O pin to GPIO4 and GPIO4 to 3V3 through 4,7k resistor.
After that I was able to read and write using "echo -n -e '\x02' > output", where output was in /sys/bus/w1/devices/29-...

I implemented my 345 nodes with a 23 1wire bus.
The idea was to simplify cost by using the 1wire GPIO on the RPi but the implementation was limited or I wasn't able to easily find the DS2408 driver implementation on the 1wire interface from RPi.
So went down this path of having a dongle per RPi to drive the 1wire using OWFS.
to answer my own question:
the 1wire implementation in RPi is limited.
USB dongle with OWFS is the only way to drive DS2408. If it is not possible, you would have to write your own extension.

The DS2408 works well with the Raspberry Pi using 1-wire, I am using a 8 port relay from http://denkovi.com.
To turn a relay on all you have to do is set the correct bit in the "/sys/bus/w1/devices/29-xxxxx/output" file, however to ensure you don't change any of the other relays it is best to read "/sys/bus/w1/devices/29-xxxx/state" and OR or XOR to turn a relay on or off.
Here is a VERY basic python script (I am by no means a programmer):
#!/usr/bin/python
import sys
from time import sleep
readfile = "/sys/bus/w1/devices/29-xxxxx/state"
writefile = "/sys/bus/w1/devices/29-xxxxx/output"
def getTheState():
try:
f = open(readfile, 'rb')
while True:
binarycontent = f.read(-1)
if not binarycontent:
break
mynum = int.from_bytes(binarycontent,byteorder=sys.byteorder)
f.close()
except IOError:
print('Error While Opening the file!')
return(mynum)
def turnOnRelay(theRelay,theState):
theTag = theRelay
# Turn On Relay
if theTag == 1 :
tagMask = 0b11111110
elif theTag == 2 :
tagMask = 0b11111101
elif theTag == 3 :
tagMask = 0b11111011
elif theTag == 4 :
tagMask = 0b11110111
elif theTag == 5 :
tagMask = 0b11101111
elif theTag == 6 :
tagMask = 0b11011111
elif theTag == 7 :
tagMask = 0b10111111
elif theTag == 8 :
tagMask = 0b01111111
else:
print("Error")
theNewState = theState & tagMask
print("theNewState",theNewState)
return theNewState
def turnOffRelay(theRelay,theState):
theTag = theRelay
# Turn Off Relay
if theTag == 1 :
tagMask = 0b00000001
elif theTag == 2 :
tagMask = 0b00000010
elif theTag == 3 :
tagMask = 0b00000100
elif theTag == 4 :
tagMask = 0b00001000
elif theTag == 5 :
tagMask = 0b00010000
elif theTag == 6 :
tagMask = 0b00100000
elif theTag == 7 :
tagMask = 0b01000000
elif theTag == 8 :
tagMask = 0b10000000
else:
print("Error")
theNewState = theState ^ tagMask
print("theNewState",theNewState)
return theNewState
def updateTheState(theNewState):
try:
newFileBytes = [theNewState]
newFile = open(writefile, "wb")
# write to file
for byte in newFileBytes:
newFile.write(byte.to_bytes(1, byteorder='big'))
except:
print('Error While Opening the file!')
def main():
print("turn relay 1 on")
x = getTheState()
y = turnOnRelay(1,x)
updateTheState(y)
sleep(5)
print("turn relay 1 off")
x = getTheState()
y = turnOffRelay(1,x)
updateTheState(y)
if __name__ == '__main__':
main()
Good luck hope this helps.
j.

Related

I2C: difference between I2C Tools and python SMBus2

I am trying to understand the i2c protocol and it's implementation through the python SMBus library and I2C Tools for Linux.
Let's look at the following I2C Sequences out of a datasheet: chapter 4.2 for the SFM3003:
I can read out the data, if I first initialise a continuous measurement with $i2cset -y 0x28 0x36 0x08 i
and then run my python script:
from smbus2 import SMBus, i2c_msg
import time
OFFSET_FLOW = -24576 # [-]
SCALEFACTOR_FLOW = 170 # [slm^-1]
OFFSET_TEMP = 0 # [-]
SCALEFACTOR_TEMP = 200 # [°C^-1]
#bus.write_byte_data(0x28, 0x36, 0x08)
msg = i2c_msg.read(0x28, 9)
bus = SMBus(1)
while True:
bus.i2c_rdwr(msg)
data = list(msg)
# JUST SOME CONVERSION FROM HERE ON
flow_bytes = data[0:2]
flow_bytes_converted = bytes(flow_bytes)
flow_raw = int.from_bytes(flow_bytes_converted, byteorder='big', signed=True)
print("flow_raw: ", flow_raw)
flow = (flow_raw-OFFSET_FLOW)/SCALEFACTOR_FLOW
print("flow: ", flow)
temp_bytes = data[3:5]
temp_bytes_converted = bytes(temp_bytes)
temp_raw = int.from_bytes(temp_bytes_converted, byteorder='big', signed=True)
print("temp_raw: ", temp_raw)
temp = (temp_raw-OFFSET_TEMP)/SCALEFACTOR_TEMP
print("temp: ", temp)
time.sleep(0.1)
If I uncomment the line bus.write_byte_data(0x28, 0x36, 0x08) and try to run the python script without initialisation from the command line($i2cset -y 0x28 0x36 0x08 i), I get an Remote I/O Error and see a NACK on my bus after writing 0x08 to the register 0x36.
So how is that command different to what I do with the I2C Linux Tools?

Second button is not working Raspberry pi pico

I'm new in micropython and I'm following the book about Raspberry pi pico. And I just wanted to know, how can I just make led ON if button1 or button2 are pressed.
Here is my code, and only the first button works, I checked, both buttons are not broken, but the second only shows the value 0 in this code.
from machine import Pin
led = Pin(15, Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(16, Pin.IN, Pin.PULL_DOWN)
while True:
if button1.value() == 1 or button2.value() == 1:
led.value(0)
elif button1.value() == 0 or button2.value() == 1:
led.value(1)
Try:
while True:
if button1.value() or button2.value():
led.value(1)
else:
led.value(0)

Reading/Writing to LSM6DSOX via SPI from Raspberry Pi

I'm having trouble reading and writing to my Adafruit LSM6DSOX IMU from my Raspberry Pi 4 running Ubuntu 20.04. I need to do it via SPI since I require the bandwidth, but I can only seem to read the WHO_AM_I register successfully. Reading/writing to any other register only returns 0x00. I have verified that I can read data off the IMU from an Arduino via SPI, but if I try to read a register other than 0x0F (the IMU_ID) I get 0x0 as a response. Any insight/ideas what could be causing this would be greatly appreciated!
EDIT: It turns out I can read the following registers:
0x0f : 0x6c
0x13 : 0x1c
0x33 : 0x1c
0x53 : 0x1c
0x73 : 0x1c
These are all random registers however, and the value 0x1C doesn't seem to correspond with anything.
This is my main.py:
import LSM6DSOX
def main():
imu=LSM6DSOX.LSM6DSOX()
imu.initSPI()
whoamI=imu.read_reg(0x0F)
while(whoamI != imu.LSM6DSOX_ID):
imu.ms_sleep(200)
print('searching for IMU')
whoamI=imu.get_id()
print(hex(whoamI))
print('found lsm6dsox IMU')
imu.spi.close()
imu.spi = None
if __name__=="__main__":
main()
This is an excerpt from my LSM6DSOX.py:
def initSPI(self):
# Setup communication SPI
self.spi = spidev.SpiDev()
self.spi.open(0, 0)
self.spi.mode=0b11 #mode 3, (mode 0 is also fine)
self.spi.max_speed_hz = 500000
return self.spi
def read_reg(self, reg, len=1):
# Set up message
buf = bytearray(len+1)
buf[0] = 0b10000000 | reg # MSB bit must be 1 to indicate a read operation. this is OR'd with the register address you want to read
resp =self.spi.xfer2(buf) #send (and recieve) data to the imu
if len==1:
return resp[1]
else:
return resp[1:] #display recieved data
def write_reg(self, reg, data, len=1):
# Set up message
buf = bytearray(len+1)
buf[0] = 0b00000000 | reg # MSB bit must be 0 to indicate a read operation. this is OR'd with the register address you want to read
buf[1:] =bytes(data)
resp =self.spi.xfer2(buf) #send (and recieve) data to the imu
return resp[1:] #display recieved data

I want to turn ON and OFF an LED with one button (micropython raspberry pi pico)

Guys Hi could you please help me with my project:
I want to turn on an LED with 2 modes:
1-with button one it should starts and after 5 second it should tun off
2-with button two, it should turn on and stays ON and then if I push Button 2 I want it to be turned off.
here is my code, I know I should compare different states but I don't understand it, I can use another button, but I like to learn how to use memory.
from machine import Pin, Timer
import time
White_LED = Pin(15, Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(13, Pin.IN, Pin.PULL_DOWN)
def func(pin):
if button2.value() == 1:
White_LED.on()
while True:
button2.irq(func)
if button1.value() == 1:
White_LED.on()
time.sleep(5)
White_LED.off()
I could manage o solve it with two functions now, but the problem is that the button2 won't react as fast as it should and I have to push it couple of times to turn the LED, ON and OFF
from machine import Pin, Timer
import time
White_LED = Pin(15, Pin.OUT)
Blue_LED = Pin(16,Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(13, Pin.IN, Pin.PULL_DOWN)
def func(pin):
if button2.value() == 1 & White_LED.value()== 0:
White_LED.on()
def func2(pin):
if button2.value() == 1 & White_LED.value()== 1:
White_LED.off()
while True:
button2.irq(func)
button2.irq(func2)
if button1.value() == 1:
White_LED.on()
time.sleep(5)
White_LED.off()
I did this and it seems it's working:
from machine import Pin, Timer
import time
White_LED = Pin(15, Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(13, Pin.IN, Pin.PULL_DOWN)
while True:
if button1.value() == 1:
White_LED.on()
time.sleep(5)
White_LED.off()
elif button2.value() == 1:
if White_LED.value()==0:
time.sleep(2)
White_LED.on()
else:
time.sleep(2)
White_LED.off()
The way you've written your code, you effectively have your while loop fighting your IRQ routines. If you just want the two buttons to act like toggle switches, the easiest solution is probably something like this:
from machine import Pin
LED = Pin(2, Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_UP)
button2 = Pin(12, Pin.IN, Pin.PULL_UP)
while True:
if LED() and not button1():
print("ON")
LED(0)
elif not LED() and not button2():
print("OFF")
LED(1)
I've tested this code on Wemos D1 Mini running micropython v1.18.
Note that I've configured the buttons as Pin.PULL_UP, and the
switches on my board are connected to ground (so pressing a switch
brings the corresponding pin to logic 0).

Micropython error : OSError: [Errno 19] ENODEV

I am trying to use pressure sensors and a LOLIN D32 pro microcontroller to measure water level. The two pressure sensors are MS5803 and BME280 below is my code
'''
import machine
from machine import Pin, I2C
import bme280, ms5803
import time
i2c= I2C(scl=Pin(22), sda=Pin(21), freq=10000)
bme1 = bme280.BME280(i2c=i2c, address = 119)
BuiltinLED = machine.Pin(5, Pin.OUT)
BuiltinLED.value(1)
WaterLevelDifference=0
def depth():
[T1,P1,H1] = bme1.raw_values #T in degrees C, P in hPa
[P2,T2] = ms5803.read(i2c=i2c, address = 118)
WaterLevelDifference = ((P2-P1)*100/9810)
return WaterLevelDifference
depth()
while WaterLevelDifference<100:
if WaterLevelDifference > 0.1:
BuiltinLED.value(0) #turns LED on
else:
depth()
time.sleep(0.5)
print(WaterLevelDifference)
'''
I have done i2c.scan() and it shows [118,119] but sometimes intermittently. What does this error mean?