Skip to content

Commit

Permalink
Merge pull request #2 from Honey-Pi/develop
Browse files Browse the repository at this point in the history
v0.1.0 release
  • Loading branch information
JavanXD authored Apr 7, 2019
2 parents 67ee577 + b553e82 commit 2fcbc29
Show file tree
Hide file tree
Showing 50 changed files with 1,377 additions and 974 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,13 @@ $RECYCLE.BIN/
# Operating System Files
# =========================
.DS_Store

# =========================
# Logfiles
# =========================
error.log

# =========================
# compiled Python files
# =========================
*.pyc
908 changes: 535 additions & 373 deletions HX711.py

Large diffs are not rendered by default.

170 changes: 170 additions & 0 deletions MAX31855.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#!/usr/bin/python
import RPi.GPIO as GPIO

class MAX31855(object):
'''Python driver for [MAX38155 Cold-Junction Compensated Thermocouple-to-Digital Converter](http://www.maximintegrated.com/datasheet/index.mvp/id/7273)
Requires:
- The [GPIO Library](https://code.google.com/p/raspberry-gpio-python/) (Already on most Raspberry Pi OS builds)
- A [Raspberry Pi](http://www.raspberrypi.org/)
'''
def __init__(self, cs_pin, clock_pin, data_pin, units = "c", board = GPIO.BCM):
'''Initialize Soft (Bitbang) SPI bus
Parameters:
- cs_pin: Chip Select (CS) / Slave Select (SS) pin (Any GPIO)
- clock_pin: Clock (SCLK / SCK) pin (Any GPIO)
- data_pin: Data input (SO / MOSI) pin (Any GPIO)
- units: (optional) unit of measurement to return. ("c" (default) | "k" | "f")
- board: (optional) pin numbering method as per RPi.GPIO library (GPIO.BCM (default) | GPIO.BOARD)
'''
self.cs_pin = cs_pin
self.clock_pin = clock_pin
self.data_pin = data_pin
self.units = units
self.data = None
self.board = board

# Initialize needed GPIO
GPIO.setmode(self.board)
GPIO.setup(self.cs_pin, GPIO.OUT)
GPIO.setup(self.clock_pin, GPIO.OUT)
GPIO.setup(self.data_pin, GPIO.IN)

# Pull chip select high to make chip inactive
GPIO.output(self.cs_pin, GPIO.HIGH)

def get(self):
'''Reads SPI bus and returns current value of thermocouple.'''
self.read()
self.checkErrors()
return getattr(self, "to_" + self.units)(self.data_to_tc_temperature())

def get_rj(self):
'''Reads SPI bus and returns current value of reference junction.'''
self.read()
return getattr(self, "to_" + self.units)(self.data_to_rj_temperature())

def read(self):
'''Reads 32 bits of the SPI bus & stores as an integer in self.data.'''
bytesin = 0
# Select the chip
GPIO.output(self.cs_pin, GPIO.LOW)
# Read in 32 bits
for i in range(32):
GPIO.output(self.clock_pin, GPIO.LOW)
bytesin = bytesin << 1
if (GPIO.input(self.data_pin)):
bytesin = bytesin | 1
GPIO.output(self.clock_pin, GPIO.HIGH)
# Unselect the chip
GPIO.output(self.cs_pin, GPIO.HIGH)
# Save data
self.data = bytesin

def checkErrors(self, data_32 = None):
'''Checks error bits to see if there are any SCV, SCG, or OC faults'''
if data_32 is None:
data_32 = self.data
anyErrors = (data_32 & 0x10000) != 0 # Fault bit, D16
noConnection = (data_32 & 0x00000001) != 0 # OC bit, D0
shortToGround = (data_32 & 0x00000002) != 0 # SCG bit, D1
shortToVCC = (data_32 & 0x00000004) != 0 # SCV bit, D2
if anyErrors:
if noConnection:
raise MAX31855Error("No Connection")
elif shortToGround:
raise MAX31855Error("Thermocouple short to ground")
elif shortToVCC:
raise MAX31855Error("Thermocouple short to VCC")
else:
# Perhaps another SPI device is trying to send data?
# Did you remember to initialize all other SPI devices?
raise MAX31855Error("Unknown Error")

def data_to_tc_temperature(self, data_32 = None):
'''Takes an integer and returns a thermocouple temperature in celsius.'''
if data_32 is None:
data_32 = self.data
tc_data = ((data_32 >> 18) & 0x3FFF)
return self.convert_tc_data(tc_data)

def data_to_rj_temperature(self, data_32 = None):
'''Takes an integer and returns a reference junction temperature in celsius.'''
if data_32 is None:
data_32 = self.data
rj_data = ((data_32 >> 4) & 0xFFF)
return self.convert_rj_data(rj_data)

def convert_tc_data(self, tc_data):
'''Convert thermocouple data to a useful number (celsius).'''
if tc_data & 0x2000:
# two's compliment
without_resolution = ~tc_data & 0x1FFF
without_resolution += 1
without_resolution *= -1
else:
without_resolution = tc_data & 0x1FFF
return without_resolution * 0.25

def convert_rj_data(self, rj_data):
'''Convert reference junction data to a useful number (celsius).'''
if rj_data & 0x800:
without_resolution = ~rj_data & 0x7FF
without_resolution += 1
without_resolution *= -1
else:
without_resolution = rj_data & 0x7FF
return without_resolution * 0.0625

def to_c(self, celsius):
'''Celsius passthrough for generic to_* method.'''
return celsius

def to_k(self, celsius):
'''Convert celsius to kelvin.'''
return celsius + 273.15

def to_f(self, celsius):
'''Convert celsius to fahrenheit.'''
return celsius * 9.0/5.0 + 32

def cleanup(self):
'''Selective GPIO cleanup'''
GPIO.setup(self.cs_pin, GPIO.IN)
GPIO.setup(self.clock_pin, GPIO.IN)

class MAX31855Error(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)

if __name__ == "__main__":

# Multi-chip example
import time
cs_pins = [4, 17, 18, 24]
clock_pin = 23
data_pin = 22
units = "f"
thermocouples = []
for cs_pin in cs_pins:
thermocouples.append(MAX31855(cs_pin, clock_pin, data_pin, units))
running = True
while(running):
try:
for thermocouple in thermocouples:
rj = thermocouple.get_rj()
try:
tc = thermocouple.get()
except MAX31855Error as e:
tc = "Error: "+ e.value
running = False
print("tc: {} and rj: {}".format(tc, rj))
time.sleep(1)
except KeyboardInterrupt:
running = False
for thermocouple in thermocouples:
thermocouple.cleanup()
124 changes: 124 additions & 0 deletions MAX6675.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/python

import RPi.GPIO as GPIO
import time

class MAX6675(object):
'''Python driver for [MAX6675 Cold-Junction Compensated Thermocouple-to-Digital Converter](http://www.adafruit.com/datasheets/MAX6675.pdf)
Requires:
- The [GPIO Library](https://code.google.com/p/raspberry-gpio-python/) (Already on most Raspberry Pi OS builds)
- A [Raspberry Pi](http://www.raspberrypi.org/)
'''
def __init__(self, cs_pin, clock_pin, data_pin, units = "c", board = GPIO.BCM):
'''Initialize Soft (Bitbang) SPI bus
Parameters:
- cs_pin: Chip Select (CS) / Slave Select (SS) pin (Any GPIO)
- clock_pin: Clock (SCLK / SCK) pin (Any GPIO)
- data_pin: Data input (SO / MOSI) pin (Any GPIO)
- units: (optional) unit of measurement to return. ("c" (default) | "k" | "f")
- board: (optional) pin numbering method as per RPi.GPIO library (GPIO.BCM (default) | GPIO.BOARD)
'''
self.cs_pin = cs_pin
self.clock_pin = clock_pin
self.data_pin = data_pin
self.units = units
self.data = None
self.board = board

# Initialize needed GPIO
GPIO.setmode(self.board)
GPIO.setup(self.cs_pin, GPIO.OUT)
GPIO.setup(self.clock_pin, GPIO.OUT)
GPIO.setup(self.data_pin, GPIO.IN)

# Pull chip select high to make chip inactive
GPIO.output(self.cs_pin, GPIO.HIGH)

def get(self):
'''Reads SPI bus and returns current value of thermocouple.'''
self.read()
self.checkErrors()
return getattr(self, "to_" + self.units)(self.data_to_tc_temperature())

def read(self):
'''Reads 16 bits of the SPI bus & stores as an integer in self.data.'''
bytesin = 0
# Select the chip
GPIO.output(self.cs_pin, GPIO.LOW)
# Read in 16 bits
for i in range(16):
GPIO.output(self.clock_pin, GPIO.LOW)
time.sleep(0.001)
bytesin = bytesin << 1
if (GPIO.input(self.data_pin)):
bytesin = bytesin | 1
GPIO.output(self.clock_pin, GPIO.HIGH)
time.sleep(0.001)
# Unselect the chip
GPIO.output(self.cs_pin, GPIO.HIGH)
# Save data
self.data = bytesin

def checkErrors(self, data_16 = None):
'''Checks errors on bit D2'''
if data_16 is None:
data_16 = self.data
noConnection = (data_16 & 0x4) != 0 # tc input bit, D2

if noConnection:
raise MAX6675Error("No Connection") # open thermocouple

def data_to_tc_temperature(self, data_16 = None):
'''Takes an integer and returns a thermocouple temperature in celsius.'''
if data_16 is None:
data_16 = self.data
# Remove bits D0-3
tc_data = ((data_16 >> 3) & 0xFFF)
# 12-bit resolution
return (tc_data * 0.25)

def to_c(self, celsius):
'''Celsius passthrough for generic to_* method.'''
return celsius

def to_k(self, celsius):
'''Convert celsius to kelvin.'''
return celsius + 273.15

def to_f(self, celsius):
'''Convert celsius to fahrenheit.'''
return celsius * 9.0/5.0 + 32

def cleanup(self):
'''Selective GPIO cleanup'''
GPIO.setup(self.cs_pin, GPIO.IN)
GPIO.setup(self.clock_pin, GPIO.IN)

class MAX6675Error(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)

if __name__ == "__main__":

# default example
cs_pin = 26
clock_pin = 18
data_pin = 19
units = "c"
thermocouple = MAX6675(cs_pin, clock_pin, data_pin, units)
running = True
while(running):
try:
try:
tc = thermocouple.get()
except MAX6675Error as e:
tc = "Error: "+ e.value
running = False
print("tc: {}".format(tc))
print(tc)
time.sleep(1)
except KeyboardInterrupt:
running = False
thermocouple.cleanup()
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
# rpi-scripts
Python Scripte, die zur Datenerfassung auf der Stockwaage ausgeführt werden.


# ![alt text](https://licensebuttons.net/l/by-nc-sa/3.0/de/88x31.png)
Dieses Werk ist lizenziert unter einer [Creative Commons Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 3.0 Deutschland Lizenz](https://creativecommons.org/licenses/by-nc-sa/3.0/de/).
HoneyPi is a measuring system based on the Raspberry Pi. It is an open source framework, which allows every beekeeper to monitor his bees. The data transfer takes place to the Internet of Things platform ThingSpeak. The measurement data is collected at the apiary and visualized in apps.
11 changes: 7 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# This file is part of HoneyPi [honey-pi.de] which is released under Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0).
# See file LICENSE or go to http://creativecommons.org/licenses/by-nc-sa/3.0/ for full license details.

Expand All @@ -10,7 +10,7 @@

from read_and_upload_all import start_measurement
from read_settings import get_settings
from utilities import stop_tv, stop_led, start_led, error_log, reboot, client_to_ap_mode, ap_to_client_mode
from utilities import stop_tv, stop_led, start_led, error_log, reboot, client_to_ap_mode, ap_to_client_mode, blink_led

# global vars
measurement = None
Expand Down Expand Up @@ -88,7 +88,7 @@ def button_pressed_falling():
error_log("Info: Too short Button press, Too long Button press OR inteference occured.")

def main():
global isActive, measurement_stop, measurement, debug, gpio
global isActive, measurement_stop, measurement, debug, gpio, GPIO_LED

settings = get_settings() # read settings for number of GPIO pin

Expand All @@ -97,7 +97,10 @@ def main():
GPIO.setwarnings(False) # Ignore warning for now
GPIO.setmode(GPIO.BCM) # Zaehlweise der GPIO-PINS auf der Platine
GPIO.setup(gpio, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Set pin 17 to be an input pin and set initial value to be pulled low (off)
GPIO.setup(21, GPIO.OUT) # Set pin 18 to led output
GPIO.setup(GPIO_LED, GPIO.OUT) # Set pin 21 to led output

# blink with LED on startup
blink_led()

# by default is AccessPoint down
stop_ap(1)
Expand Down
Loading

0 comments on commit 2fcbc29

Please sign in to comment.