I2C in Raspbery Pi 3 using smbus - python

I'm trying to interface my accelerometer ADXL3458 to my Raspberry Pi 3 running in ubuntu mate. I have install all the necessary package require for the I2C communication. When I perform this command i2cdetect -y 1 I get this results.
Now I run this Python code
#!/usr/bin/env python
import smbus
import time
import math
from math import sin, cos, pi
bus = smbus.SMBus(1)
print bus
ACC_ADRESS = 0x53
acc_x = 0.0
acc_y = 0.0
acc_z = 0.0
def writeACC (register, value):
bus.write_byte_data(ACC_ADRESS, register, value)
return -1
def readACC_byte ( addr):
return bus.read_byte_data(ACC_ADRESS, addr)
def readACC_word (addr):
LSB = bus.read_byte_data(ACC_ADRESS, addr)
MSB = bus.read_byte_data(ACC_ADRESS, addr + 1)
val = (MSB << 8) | LSB
return val
def setupACC ():
# Sleep mode
writeACC(0x2D, 0)
# Mesurement mode
writeACC(0x2D, 8)
# enable Autu sleep mode
writeACC(0x2D, 16)
while True:
time.sleep(0.1)
acc_x = readACC_word(0x32)
acc_y = readACC_word(0x34)
acc_z = readACC_word(0x36)
print "Acc_x :\n", acc_x
print "Acc_y :\n", acc_y
print "Acc_z :\n", acc_z
time.sleep(0.5)
if __name__ == '__main__':
setupACC()
And I get this result in the oscilloscope
This infer that my I2C communication is successful. But in the result that I'm printing shows no value in it
Can please help with problem that I'm facing. Is it anything that I'm doing wrong?
thank you

Auto sleep mode was should not active. Upon commenting
#writeACC(0x2D, 16)
is working fine.

Related

setting rpi-gpio pin on high after running a python script

I'm building a photogrametry setup with raspberry pi and stepper motor.
The python script runs fine, but i got a problem with setting a pin to high after the script ran through.
The stepper driver has an enable input, which diasables the motor with high input, so i set the pin (gpio26) on high on boot with pigpio, this works fine. While running the python script, the pin is set on low, so the stepper can proceed, after proceeding i want to set the pin on high again.
i tried following commands:
os.system('pigs w 26 1') and
subprocess.call("pigs w 26 1", shell=True)
for a moment they work, but after exiting the script the pin is set on low again.
It's like the commands are resetted after the script stops.
Where is my fault?
Thank you
Edit:
Here is the gpio related code:
import os, sys
import subprocess
from time import sleep
from gpiozero import DigitalOutputDevice as stepper
def InitGPIO():
try:
global step_pul #pulse
global step_en #enable
step_pul=stepper(21)
step_en=stepper(26)
print ("GPIO initialisiert.")
except:
print ("Fehler bei der GPIO-Initialisierung.")
def motor_step():
SPR=40000 #steps per rotation
step_count = SPR
delay = .000025
for x in range(step_count):
step_pul.on()
sleep(delay)
step_pul.off()
sleep(delay)
InitGPIO()
step_en.off()
for i in range(1):
#camTrigger(1)
motor_step()
#os.system('sudo -u root -S pigs w 26 1')
subprocess.call("pigs w 26 1", shell=True)
When i type pigs w 26 1 in the shell, it works...
To make my comment an answer:
Gpiozero only resets the pins it touches, so if you don't initialize or touch pin 26 with gpiozero (i.e. replace step_en.off() with pigs w 26 0 and don't even initialize step_en), it shouldn't also reset the pin:
import os
import time
import gpiozero
step_pul = gpiozero.DigitalOutputDevice(21)
def motor_step():
SPR = 40000 # steps per rotation
step_count = SPR
delay = .000025
for x in range(step_count):
step_pul.on()
time.sleep(delay)
step_pul.off()
time.sleep(delay)
# Enable motor
os.system("pigs w 26 0")
for i in range(1):
# camTrigger(1)
motor_step()
# Disable motor
os.system("pigs w 26 1")

Run Script as parallel Subprocess

i'm pretty new to python, so my knowledge is quiet basic. (i'm a system engineer)
i have a raspberry pi, an led strip and a python script to simulate a fire on the led strip :D
now i want to start the script by pressing my flic button. i found the fliclib sdk on github and installed it. my problem is now, how to handle the event correctly. i successfully can start the script, but i'd like to stop it by doublepress the flic button. but it seems like i'm stuck in the fire.py script as soon as i press the button once. can anybody help me how to set this up correctly please? :-)
Edit after suggestion:
i just edited my scripts as the following. i can see when the button is pressed once or twice with this output:
Starting Fire
Stopping Fire
but the led wont turn on, seems like, fire.py isn't opened or something like that.. when i set button=1 in fire.py itself, the fire turns on.
main.py
#!/usr/bin/env /usr/bin/python3
# -*- coding: utf-8 -*-
import flicbutton
import fire
button = 0
flicbutton.py
#!/usr/bin/env /usr/bin/python3
# -*- coding: utf-8 -*-
import fliclib
client = fliclib.FlicClient("localhost")
MyButton1 = '80:e4:da:71:83:42' #turquoise flic button
def got_button(bd_addr):
cc = fliclib.ButtonConnectionChannel(bd_addr)
cc.on_button_single_or_double_click_or_hold = some_handler
cc.on_connection_status_changed = \
lambda channel, connection_status, disconnect_reason: \
print(channel.bd_addr + " " + str(connection_status) + (" " + str(disconnect_reason) if connection_status == fliclib.ConnectionStatus.Disconnected else ""))
client.add_connection_channel(cc)
def got_info(items):
print(items)
for bd_addr in items["bd_addr_of_verified_buttons"]:
got_button(bd_addr)
def some_handler(channel, click_type, was_queued, time_diff):
if channel.bd_addr == MyButton1:
try:
if click_type == fliclib.ClickType.ButtonSingleClick:
print("Starting Fire")
button=1
if click_type == fliclib.ClickType.ButtonDoubleClick:
print("Stopping Fire")
button=2
if click_type == fliclib.ClickType.ButtonHold:
print("ButtonHold has not been assigned an action")
except Exception:
import datetime
print('An error occured: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()))
client.get_info(got_info)
client.on_new_verified_button = got_button
client.handle_events()
fire.py
import RPi.GPIO as GPIO
import threading
import time
import random
import math
R = 17
G = 22
pwms = []
intensity = 1.0
def initialize_gpio():
GPIO.setmode(GPIO.BCM)
GPIO.setup([17,22], GPIO.OUT)
def red_light():
p = GPIO.PWM(R, 300)
p.start(100)
pwms.append(p)
while True:
p.ChangeDutyCycle(min(random.randint(50, 100) * math.pow(intensity + 0.1, 0.75), 100) if intensity > 0 else 0)
rand_flicker_sleep()
def green_light():
global green_dc
p = GPIO.PWM(G, 300)
p.start(0)
pwms.append(p)
while True:
p.ChangeDutyCycle(random.randint(5, 10) * math.pow(intensity, 2) if intensity > 0 else 0)
rand_flicker_sleep()
def rand_flicker_sleep():
time.sleep(random.randint(3,10) / 100.0)
def fan_the_flame(_):
global intensity
intensity = min(intensity + 0.25, 1.0)
def light_candle():
threads = [
threading.Thread(target=red_light),
threading.Thread(target=green_light),
## threading.Thread(target=burning_down)
]
for t in threads:
t.daemon = True
t.start()
for t in threads:
t.join()
def startfire():
try:
initialize_gpio()
print("\nPress ^C (control-C) to exit the program.\n")
light_candle()
except KeyboardInterrupt:
pass
finally:
for p in pwms:
p.stop()
def stopfire():
GPIO.cleanup()
#if __name__ == '__main__':
# main()
if button == 1:
startfire()
if button == 2:
stopfire()
Have a common (global variable) that both codes can read, you can put this in a standalone file that both codes can access. So script 1 updates this variable like
if(single press): variable=1
elif(double press): variable=2
then in fire.py you can poll the variable.
if(varaible==1): start/stop fire
elif(variable==2): stop/start fire
else: #throw error
I'm sure there are more efficient ways to do this, but this method should be the easiest to understand.

How to read data into Raspberry Pi using modbus-tk?

So I'm doing a project where I want my Raspberry Pi 4 to communicate through Modbus. I've bought a shield to enable RS485 communication from the Pi and I've been modifying the demo code (Software/Test Codes/MODBUS/rtumaster.py) and have been using a slave simulator on my computer to test.
I'm reaching out because I've gotten stuck on trying to read data from my slave. The command seems to go through okay (or the slave simulator doesn't complain is perhaps better to say), but I don't know how to get the data into my program. I've been trying something like this:
read = logger.info(master.execute(1, cst.READ_INPUT_REGISTERS, 5, 1))
And then trying to print that value to check, but it just returns 'None' instead of my value.
Any help is appreciated.
Current code:
## To install dependencies:
## sudo pip3 install modbus-tk
##################################################################################################
import serial
import fcntl
import os
import struct
import termios
import array
#import modbus lib
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus as modbus
#import modbus_tk.modbus_rtu as modbus_rtu
from modbus_tk import modbus_rtu
# RS485 ioctls define
TIOCGRS485 = 0x542E
TIOCSRS485 = 0x542F
SER_RS485_ENABLED = 0b00000001
SER_RS485_RTS_ON_SEND = 0b00000010
SER_RS485_RTS_AFTER_SEND = 0b00000100
SER_RS485_RX_DURING_TX = 0b00010000
# rs 485 port
ser1 = serial.Serial("/dev/ttySC0",19200)
ser2 = serial.Serial("/dev/ttySC1",9600)
def rs485_enable():
buf = array.array('i', [0] * 8) # flags, delaytx, delayrx, padding
#enable 485 chanel 1
fcntl.ioctl(ser1, TIOCGRS485, buf)
buf[0] |= SER_RS485_ENABLED|SER_RS485_RTS_AFTER_SEND
buf[1] = 0
buf[2] = 0
fcntl.ioctl(ser1, TIOCSRS485, buf)
#enable 485 chanel 2
fcntl.ioctl(ser2, TIOCGRS485, buf)
buf[0] |= SER_RS485_ENABLED|SER_RS485_RTS_AFTER_SEND
buf[1] = 0
buf[2] = 0
fcntl.ioctl(ser2, TIOCSRS485, buf)
#end of rs485_enable():
if __name__ == '__main__':
logger = modbus_tk.utils.create_logger("console")
rs485_enable()
#set modbus master
master = modbus_rtu.RtuMaster(
serial.Serial(port= '/dev/ttySC0',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
xonxoff=0)
)
master.set_timeout(5.0)
master.set_verbose(True)
logger.info("connected")
read = logger.info(master.execute(1, cst.READ_INPUT_REGISTERS, 5, 1))
print("Value is: ", read)

Return the value to 0 after reaching specific value in Python and Rpi

I have an encoder attached to Raspberrypi. The motor is connected to arduino, based on the value of encoder, the motor will function. I am able to send the value from rpi to arduino using Serial communication(USB). The problem is, the value keeps on increasing (eg. 1, 2, 3, .....). I want that the value of the encoder should start from 0 once it reads 10 as shown in code below. Help would be appreciated.
import RPi.GPIO as GPIO
import time
import serial
ser=serial.Serial('/dev/ttyACM0',9600)
#ser.write(b'0')
GPIO.setmode (GPIO.BCM)
GPIO.setwarnings(True)
pin_A = 17
pin_B = 18
Encoder_Count = 0
A_Pos2=0
GPIO.setup (pin_A, GPIO.IN)
GPIO.setup (pin_B, GPIO.IN)
A_Pos = 0
A_Last = "00"
STATE = {"0001":1,"0010":-1,"0100":-1,"0111":1,"1000":1,"1011":-1, "1101":-1, "1110":1}
def Encoder1(channel1):
global Encoder_Count,A_Pos,A_Last,STATE
now = str(GPIO.input(17)) + str(GPIO.input(18))
key = A_Last + now
if key in STATE:
direction = STATE[key]
A_Last = now
A_Pos +=direction
GPIO.add_event_detect (pin_A, GPIO.BOTH, callback=Encoder1)
GPIO.add_event_detect (pin_B, GPIO.BOTH, callback=Encoder1)
#A_Pos2=0
while(1):
# ser.write(b'1')
A_Pos2= A_Pos/(1600)
print (A_Pos2)
if (A_Pos2 >10):
ser.write(b'0')
time.sleep(0.01)
GPIO.cleanup()
This can be done with modulo operation, unless i am missing something:
if (A_Pos2 >10):
A_Pos2 = A_Pos2 % 10
That will reset A_Pos2 to 0 once it reaches 10.

Pulse width reader printing same value every time

I'm connecting my raspberry pi to a 2.4ghz rc reciever, and I am trying to use python to interpret the pulse width signal. I am using an input pin to read the time while there is no input, then the time when there is an input, then subtracting the two.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(13,GPIO.IN)
GPIO.setup(15,GPIO.OUT)
GPIO.output(15,GPIO.HIGH)
start = time.time()
stop = time.time()
x = 0
y = 0
while(x == 0):
if(GPIO.input(13) == 0):
start = time.time()
x = 1
while(y == 0):
if(GPIO.input(13) == 1):
stop = time.time()
y = 1
Width = stop-start
print(Width)
GPIO.cleanup()
The issue I am having is that no matter how long I make the pulse width (by manually connecting and disconnecting pin 13 and 15), it prints ~.006. It also will not print until I disconnect the pins from each other, although I haven't been able to figure out why.
Pin 13 might be floating. I'd suggest you replace ...
GPIO.setup(13,GPIO.IN)
... with ...
GPIO.setup(13,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
Here's an example of how to do this with interrupts:
#!/usr/bin/env python3
# example of reading PWM with GPIO interrupts
# Warning: Linux isn't built for real-time applications.
# A Raspberry Pi with Jessie will not produce reliable results
# That said...
import RPi.GPIO as GPIO
import time
GPIOpin_IN = 13
GPIOpin3v3 = 1 # fixed at 3v3 volts
myStart = None
myStop = None
GPIO.setmode(GPIO.BOARD)
GPIO.setup(GPIOpin_IN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
def pinGoesUp(gpioIdentity):
myStart = time.time()
def pinGoesDown(gpioIdentity):
myStop = time.time()
GPIO.add_event_detect(GPIOpin_IN, GPIO.RISING, callback=pinGoesUp)
GPIO.add_event_detect(GPIOpin_IN, GPIO.FALLING, callback=pinGoesDown)
while True:
if myStop < myStart:
Width = stop-start
print(Width)`
documentation on gpio input.
On a side note, you're going to have difficulty getting reliable readings. Jessie is not intended to provide real-time interaction, and frequently takes small vacations to do other tasks.

Categories