diff --git a/README.md b/README.md index 1d723b9..57207d8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,21 @@ # raspicar -Get and Display car sensors \ No newline at end of file +Get and Display car sensors + +## Requirements + +### Hardware + +- Raspberry Pi Zero or other Raspberry Pi version (3 or 4) +- [Optional] UBEC DC/DC Step-Down (Buck) Converter - 5V @ 3A output +- Adafruit 0.56" 4-Digit 7-Segment Display w/I2C Backpack +- Voltage sensor (tested with Grove - Voltage Divider) +- MCP3008 - 8-Channel 10-Bit ADC With SPI Interface +- Momentary switch button + +### Software + +- Raspios +- pip3 (sudo apt install python3-pip) +- HT16K33 Library (sudo pip3 install adafruit-circuitpython-ht16k33) +- Pillow Library (sudo apt install python3-pil) diff --git a/raspicar.py b/raspicar.py new file mode 100644 index 0000000..9a80847 --- /dev/null +++ b/raspicar.py @@ -0,0 +1,123 @@ +import time +import board +import RPi.GPIO as GPIO + +from datetime import datetime +from adafruit_ht16k33.segments import Seg7x4 + +# ADC configuration +CLK = 11 +MISO = 9 +MOSI = 10 +CS = 8 +CHANNEL = 0 # By default read sensor 0 + +# Display configuration +i2c = board.I2C() +display = Seg7x4(i2c) + +# Button +BUTTON = 5 # GPIO5 + +# Function called on push button (change sensor) +def handlePushButton(button): + global CHANNEL + CHANNEL += 1 + if ( CHANNEL > 8 ): + CHANNEL = 0 + + display.print(" :"+str(CHANNEL)+"-") + + +# Init program +def init(): + # Set display + display.brightness = 1 + display.blink_rate = 0 # Between 0 and 3 + + GPIO.setwarnings(False) + GPIO.setmode(GPIO.BCM) + + GPIO.setup(BUTTON, GPIO.IN, pull_up_down=GPIO.PUD_UP) + GPIO.setup(MOSI, GPIO.OUT) + GPIO.setup(MISO, GPIO.IN) + GPIO.setup(CLK, GPIO.OUT) + GPIO.setup(CS, GPIO.OUT) + + # Add button event + GPIO.add_event_detect(BUTTON, GPIO.FALLING, callback=handlePushButton, bouncetime=250) + + pass + + +#read SPI data from MCP3008(or MCP3204) chip,8 possible adc's (0 thru 7) +def readadc(adcnum, clockpin, mosipin, misopin, cspin): + if ((adcnum > 7) or (adcnum < 0)): + return -1 + + GPIO.output(cspin, True) + GPIO.output(clockpin, False) # start clock low + GPIO.output(cspin, False) # bring CS low + + commandout = adcnum + commandout |= 0x18 # start bit + single-ended bit + commandout <<= 3 # we only need to send 5 bits here + for i in range(5): + if (commandout & 0x80): + GPIO.output(mosipin, True) + else: + GPIO.output(mosipin, False) + + commandout <<= 1 + GPIO.output(clockpin, True) + GPIO.output(clockpin, False) + + adcout = 0 + + # read in one empty bit, one null bit and 10 ADC bits + for i in range(12): + GPIO.output(clockpin, True) + GPIO.output(clockpin, False) + adcout <<= 1 + if (GPIO.input(misopin)): + adcout |= 0x1 + + GPIO.output(cspin, True) + + #adcout >>= 1 # first bit is 'null' so drop it + return adcout + + +# Main programm +def main(): + init() + time.sleep(2) + print("Let's go!") + + while True: + if ( CHANNEL == 8 ): # Last sensor => clock mode + now = datetime.now() + printableValue = now.strftime("%H:%M") + else: + # Get current sensor value + ad_value = readadc(CHANNEL, CLK, MOSI, MISO, CS) + value = ad_value*(3.3/1024)*5 + # Format value with 2 decimals + printableValue = f"{value:.02f}" + + # Clear display + display.fill(0) + # Print new value + display.print(str(printableValue)) + + # Wait between next loop + time.sleep(10) + + +if __name__ =='__main__': + try: + main() + except KeyboardInterrupt: + pass + +print("GoodBye!")