Giter VIP home page Giter VIP logo

raspberry-pi-sample-code's Introduction

Preparing the Raspberry Pi

Install the latest Raspberry Pi OS

Follow the instructions on this page to get Raspberry Pi OS running https://www.raspberrypi.org/downloads/raspberry-pi-os/

Expand file system

Expand file system by following this: https://www.raspberrypi.org/documentation/configuration/raspi-config.md

Update and Upgrade Packages

sudo apt-get update
sudo apt-get upgrade

Download sample code.

cd ~
git clone https://github.com/AtlasScientific/Raspberry-Pi-sample-code.git

FTDI MODE

Installing dependencies for FTDI adaptors

  • Install libftdi package.

      sudo apt-get install libftdi-dev
    
  • Install pylibftdi python package.

      sudo pip install pylibftdi
    
  • Create SYMLINK of the FTDI adaptors.

    The following will allow ordinary users (e.g. โ€˜piโ€™ on the RPi) to access to the FTDI device without needing root permissions:

    If you are using device with root permission, just skip this step.

    Create udev rule file by typing sudo nano /etc/udev/rules.d/99-libftdi.rules and insert below:

      SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", GROUP="dialout", MODE="0660", SYMLINK+="FTDISerial_Converter_$attr{serial}"
    

    Press CTRL+X, Y and hit Enter to save & exit.

    Restart udev service to apply changes above.

      sudo service udev restart
    
  • Modify FTDI python driver

    Since our FTDI devices use other USB PID(0x6015), we need to tweak the original FTDI Driver.

      sudo nano /usr/local/lib/python2.7/dist-packages/pylibftdi/driver.py
    

    Move down to the line 70 and add 0x6015 at the end of line.

    Original line:

      USB_PID_LIST = [0x6001, 0x6010, 0x6011, 0x6014]
    

    Added line:

      USB_PID_LIST = [0x6001, 0x6010, 0x6011, 0x6014, 0x6015]        
    
  • Testing Installation.

    Connect your device, and run the following (as a regular user):

      python -m pylibftdi.examples.list_devices
    

    If all goes well, the program should report information about each connected device.

    If no information is printed, but it is when run with sudo, a possibility is permissions problems - see the section under Linux above regarding udev rules.

    You may get result like this:

      FTDI:FT230X Basic UART:DA00TN73
    

    FTDI adaptors has its own unique serial number.

    We need this to work with our sensors.

    In the result above, serial number is DA00TN73.

Using pylibftdi module for Atlas Sensors.

Please remember the serial number of your device and run the sample code.

cd ~/Raspberry-Pi-sample-code
sudo python ftdi.py

Input the serial number and you can see the sensor's information and also sensor's LED status as well.

For more details on the commands & responses, please refer the Datasheets of Atlas Sensors.

I2C MODE

Enable I2C bus on the Raspberry Pi

Enable I2C bus on the Raspberry Pi by following this:

https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-i2c

You can confirm that the setup worked and sensors are present with the sudo i2cdetect -y 1 command.

Test Sensor

Run the sample code below:

cd ~/Raspberry-Pi-sample-code
sudo python i2c.py

When the code starts up a list of commands will be shown.

For more details on the commands & responses, please refer to the Datasheets of the Atlas Scientific Sensors.

UART MODE

Preventing Raspberry Pi from using the serial port

The Broadcom UART appears as /dev/ttyS0 under Linux on every Pi. The Pi 4 has additional UARTS, see below for instruction on how to use them

There are several minor things in the way if you want to have dedicated control of the primary serial port on a Raspberry Pi.

  • Firstly, the kernel will use the port as controlled by kernel command line contained in /boot/cmdline.txt.

    The file will look something like this:

      dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
    

    The console keyword outputs messages during boot, and the kgdboc keyword enables kernel debugging.

    You will need to remove all references to ttyAMA0.

    So, for the example above /boot/cmdline.txt, should contain:

      dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
    

    You must be root to edit this (e.g. use sudo nano /boot/cmdline.txt).

    Be careful doing this, as a faulty command line can prevent the system booting.

  • Secondly, after booting, a login prompt appears on the serial port.

    This is controlled by the following lines in /etc/inittab:

      #Spawn a getty on Raspberry Pi serial line
      T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
    

    You will need to edit this file to comment out the second line, i.e.

      #T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
    
  • Finally you will need to reboot the Raspberry Pi for the new settings to take effect.

    Once this is done, you can use /dev/ttyS0 like any normal Linux serial port, and you won't get any unwanted traffic confusing the attached devices.

To double-check, use

cat /proc/cmdline

to show the current kernel command line, and

ps aux | grep ttyS0

to search for getty processes using the serial port.

Ensure PySerial is installed for Python.

sudo pip install pyserial

Run the below Python script:

cd ~/Raspberry-Pi-sample-code
sudo python uart.py

Alternate UARTS on Pi4:

The raspberry pi 4 has 6 uarts

To demonstrate alternate UART usage, we're going to enable UART 5 Note that other UARTs share their pins with other peripherals, so those peripherals may have to be disabled to use them

UART 5 uses pins 32 (TX) and 33 (RX) on the raspberry pi 40 pin header

Go into the boot configuration

sudo nano /boot/config.txt 

and add the lines

enable_uart=1
dtoverlay=uart5

then restart the raspberry pi

To use this port in the uart sample code uart.py change line 70 to:

usbport = '/dev/ttyAMA1'

Note that it may be a different ttyAMA depending on your setup

raspberry-pi-sample-code's People

Contributors

atlas-scientific avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

raspberry-pi-sample-code's Issues

IndexError: list index out of range

Followed instructions for i2C on a RTD sensor on a raspberry pi 4 with the latest version of Raspian.

sudo python i2c.py or sudo python3 i2.py both give the following

Sensor is detected correctly by sudo i2cdetect -y 1

Traceback (most recent call last):
File "i2c.py", line 146, in
main()
File "i2c.py", line 59, in main
device_list = get_devices()
File "i2c.py", line 29, in get_devices
moduletype = response.split(",")[1]
IndexError: list index out of range

OSError: [Errno 121] Remote I/O error

Hello,
I have the ORP and PH sensors since few years without issue. I read the sensors from RexyGen automation program that I made and have no issue. I have stopped the program (to ensure it was not communicating while I want to use Atlas Scientific software to calibrate the probes).
I installed the latest version from Git (I re-imaged my PI as the SD Card died). I am always getting error when trying to use the i2c.py with python 2 or 3. It used to worked before and I know I can communicate with the sensors as my automation has no issue. So there is really something not working and I would expect this to work. I tried to use and older version from Git and still had issue.

Here are the errors. As you can see we can see the PH and ORP at 62 and 63.

root@raspPool:/Raspberry-Pi-sample-code-latest# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- 18 -- -- 1b -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- 62 63 -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77
root@raspPool:
/Raspberry-Pi-sample-code-latest# python3 i2c.py
Traceback (most recent call last):
File "i2c.py", line 146, in
main()
File "i2c.py", line 59, in main
device_list = get_devices()
File "i2c.py", line 28, in get_devices
response = device.query("I")
File "/root/Raspberry-Pi-sample-code-latest/AtlasI2C.py", line 163, in query
self.write(command)
File "/root/Raspberry-Pi-sample-code-latest/AtlasI2C.py", line 84, in write
self.file_write.write(cmd.encode('latin-1'))
OSError: [Errno 121] Remote I/O error

AtlasI2C is removing the digits to the left of the decimal in readings

Instead of return, for example "3.259", the read() method returns ".259". The cause of this is two slice operations which remove the leading digit:

This line calls the handle_raspi_glitch() method with response[1:].

Then this line inside handle_raspi_glitch() is also doing response[1:].

The fix is to only slice the response object once.

I should also note that this only effects Python 3.

Raspberry Pi and systemd

Hi,

I have Tentacle T3 for Raspberry Pi working and and when I Call the i2c.py it works fine. However, I wanted to initiate the program script when the pi is turned on. I have written the systemd script that call the i2c.py. the systemd command runs fine when the pi reboots. However it does not when the pi starts at first. Is there any suggession to get this worked?

Using depreciated String.Split methods

Updated code to work with python 2.7:

`#!/usr/bin/python

import io # used to create file streams
from io import open
import fcntl # used to access I2C parameters like addresses

import time # used for sleep delay and timestamps
import string # helps parse strings

class AtlasI2C:
long_timeout = 1.5 # the timeout needed to query readings and calibrations
short_timeout = .5 # timeout for regular commands
default_bus = 1 # the default bus for I2C on the newer Raspberry Pis, certain older boards use bus 0
default_address = 102 # the default address for the sensor
current_addr = default_address

def __init__(self, address=default_address, bus=default_bus):
	# open two file streams, one for reading and one for writing
	# the specific I2C channel is selected with bus
	# it is usually 1, except for older revisions where its 0
	# wb and rb indicate binary read and write
	self.file_read = io.open("/dev/i2c-"+str(bus), "rb", buffering=0)
	self.file_write = io.open("/dev/i2c-"+str(bus), "wb", buffering=0)

	# initializes I2C to either a user specified or default address
	self.set_i2c_address(address)

def set_i2c_address(self, addr):
	# set the I2C communications to the slave specified by the address
	# The commands for I2C dev using the ioctl functions are specified in
	# the i2c-dev.h file from i2c-tools
	I2C_SLAVE = 0x703
	fcntl.ioctl(self.file_read, I2C_SLAVE, addr)
	fcntl.ioctl(self.file_write, I2C_SLAVE, addr)
	self.current_addr = addr

def write(self, cmd):
	# appends the null character and sends the string over I2C
	cmd += "\00"
	self.file_write.write(cmd.encode('latin-1'))

def read(self, num_of_bytes=31):
	# reads a specified number of bytes from I2C, then parses and displays the result
	res = self.file_read.read(num_of_bytes)         # read from the board
	if type(res[0]) is str:					# if python2 read
		response = [i for i in res if i != '\x00']
		if ord(response[0]) == 1:             # if the response isn't an error
			# change MSB to 0 for all received characters except the first and get a list of characters
			# NOTE: having to change the MSB to 0 is a glitch in the raspberry pi, and you shouldn't have to do this!
			char_list = list(map(lambda x: chr(ord(x) & ~0x80), list(response[1:])))
			return "Command succeeded " + ''.join(char_list)     # convert the char list to a string and returns it
		else:
			return "Error " + str(ord(response[0]))
			
	else:									# if python3 read
		if res[0] == 1: 
			# change MSB to 0 for all received characters except the first and get a list of characters
			# NOTE: having to change the MSB to 0 is a glitch in the raspberry pi, and you shouldn't have to do this!
			char_list = list(map(lambda x: chr(x & ~0x80), list(res[1:])))
			return "Command succeeded " + ''.join(char_list)     # convert the char list to a string and returns it
		else:
			return "Error " + str(res[0])

def query(self, string):
	# write a command to the board, wait the correct timeout, and read the response
	self.write(string)

	# the read and calibration commands require a longer timeout
	if((string.upper().startswith("R")) or
		(string.upper().startswith("CAL"))):
		time.sleep(self.long_timeout)
	elif string.upper().startswith("SLEEP"):
		return "sleep mode"
	else:
		time.sleep(self.short_timeout)

	return self.read()

def close(self):
	self.file_read.close()
	self.file_write.close()

def list_i2c_devices(self):
	prev_addr = self.current_addr # save the current address so we can restore it after
	i2c_devices = []
	for i in range (0,128):
		try:
			self.set_i2c_address(i)
			self.read(1)
			i2c_devices.append(i)
		except IOError:
			pass
	self.set_i2c_address(prev_addr) # restore the address we were using
	return i2c_devices

def main():
device = AtlasI2C() # creates the I2C port object, specify the address or bus if necessary

print(">> Atlas Scientific sample code")
print(">> Any commands entered are passed to the board via I2C except:")
print(">>   List_addr lists the available I2C addresses.")
print(">>   Address,xx changes the I2C address the Raspberry Pi communicates with.")
print(">>   Poll,xx.x command continuously polls the board every xx.x seconds")
print(" where xx.x is longer than the %0.2f second timeout." % AtlasI2C.long_timeout)
print(">> Pressing ctrl-c will stop the polling")

real_raw_input = vars(__builtins__).get('raw_input', input)

# main loop
while True:
	user_cmd = real_raw_input("Enter command: ")

	if user_cmd.upper().startswith("LIST_ADDR"):
		devices = device.list_i2c_devices()
		for i in range(len (devices)):
			print( devices[i])

	# address command lets you change which address the Raspberry Pi will poll
	elif user_cmd.upper().startswith("ADDRESS"):
		addr = int(user_cmd.split(',')[1])
		device.set_i2c_address(addr)
		print("I2C address set to " + str(addr))

	# continuous polling command automatically polls the board
	elif user_cmd.upper().startswith("POLL"):
		delaytime = float(user_cmd.split(',')[1])
		#delaytime = float((user_cmd.split(user_cmd, ',')[1]))
                    
                    
		# check for polling time being too short, change it to the minimum timeout if too short
		if delaytime < AtlasI2C.long_timeout:
			print("Polling time is shorter than timeout, setting polling time to %0.2f" % AtlasI2C.long_timeout)
			delaytime = AtlasI2C.long_timeout

		# get the information of the board you're polling
		info = device.query("I").split(",")[1]
		#info = string.split(device.query("I"), ",")[1]
		print("Polling %s sensor every %0.2f seconds, press ctrl-c to stop polling" % (info, delaytime))

		try:
			while True:
				print(device.query("R"))
				time.sleep(delaytime - AtlasI2C.long_timeout)
		except KeyboardInterrupt: 		# catches the ctrl-c command, which breaks the loop above
			print("Continuous polling stopped")

	# if not a special keyword, pass commands straight to board
	else:
		if len(user_cmd) == 0:
			print( "Please input valid command.")
		else:
			try:
				print(device.query(user_cmd))
			except IOError:
				print("Query failed \n - Address may be invalid, use List_addr command to see available addresses")

if name == 'main':
main()

`

Cannot get i2c readings with USB board

Hi, I am trying to get readings from my EC sensor. I have already connected my EC chip to my USB EZO isolated board. The board is detected by my rapsberry pi, but when I send the R command to get a reading I cannot get any return value

`pi@aws-rpi02:~/Raspberry-Pi-sample-code $ sudo python2 ftdi.py

Welcome to the Atlas Scientific Raspberry Pi FTDI Serial example.

Any commands entered are passed to the board via UART except:
Poll,xx.x command continuously polls the board every xx.x seconds
Pressing ctrl-c will stop the polling

Press enter to receive all data in buffer (for continuous mode) 

Discovered FTDI serial numbers:
('\nIndex: ', 0, ' Serial: ', u'DO009HTS')

Please select a device index: 0

('>> Opened device ', u'DO009HTS')

Any commands entered are passed to the board via FTDI:
Enter command: R
Enter command:`

If I run the i2cdectec command I dont see the chip address:

pi@aws-rpi02:~/Raspberry-Pi-sample-code $ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

However if I connect the EC chip directly to my raspberry pi I can get readings from it:

`pi@aws-rpi02:~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- 64 -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@aws-rpi02:~ $ cd Raspberry-Pi-sample-code/
pi@aws-rpi02:/Raspberry-Pi-sample-code $ ls
AtlasI2C.py AtlasI2C.pyc ftdi.py i2c.py LICENSE README.md uart.py
pi@aws-rpi02:
/Raspberry-Pi-sample-code $ sudo python2 i2c.py

Atlas Scientific I2C sample code
Any commands entered are passed to the default target device via I2C except:

  • Help
    brings up this menu
  • List
    lists the available I2C circuits.
    the --> indicates the target device that will receive individual commands
  • xxx:[command]
    sends the command to the device at I2C address xxx
    and sets future communications to that address
    Ex: "102:status" will send the command status to address 102
  • all:[command]
    sends the command to all devices
  • Poll[,x.xx]
    command continuously polls all devices
    the optional argument [,x.xx] lets you set a polling time
    where x.xx is greater than the minimum 1.50 second timeout.
    by default it will poll every 1.50 seconds

Pressing ctrl-c will stop the polling

--> EC 100

Enter command: r
Success EC 100: 13090
Enter command: r
Success EC 100: 13090
Enter command: r
Success EC 100: 13090
Enter command: r
Success EC 100: 13090
Enter command: r
Success EC 100: 13090
Enter command: r
Success EC 100: 13010
Enter command: r
Success EC 100: 13010
`

Any input why I cannot get readings using the USB isolated board but I can get readinds from the EC chip connected directly to my RPI?

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.