Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Script/__pycache__
.lgd-nfy0
rtDb.json
23 changes: 23 additions & 0 deletions Script/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
CONFIG_YAML_FILE = "config.yaml"
RT_DB_FILE = "rtDb.json"

INPUT = 0
OUTPUT = 1

PULL_UP = 0
PULL_DOWN = 1

HIGH = 1
LOW = 0

LCD_MODULE_NO_OF_ROW = 4
LCD_MODULE_NO_OF_COLUMN = 20

POSITION_LEFT = -1
POSITION_MIDDLE = 0
POSITION_RIGHT = 1

ROW_NO_0 = 0
ROW_NO_1 = 1
ROW_NO_2 = 2
ROW_NO_3 = 3
66 changes: 66 additions & 0 deletions Script/lcd20x4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from RPLCD.i2c import CharLCD

class Lcd20x4:
def __init__(self, i2cAddress: int, column: int, row: int):
self.i2cAddress = i2cAddress
self.port = 0x01
self.columns = column
self.rows = row
self.dotSize = 8

self.init()


def init(self):
self._lcd = CharLCD(
i2c_expander = 'PCF8574',
address = self.i2cAddress,
port = self.port,
cols = self.columns,
rows = self.rows,
dotsize = self.dotSize)
self.clean()

def clean(self):
self._lcd.clear()


def setLcdCursor(self, row: int, column: int):
self._lcd.cursor_pos = (row, column)


def write(self,
text : str,
row : int = -1,
column : int = -1,
padding : bool = False,
center : bool = False):

# if only row is passrd but no column value
if row != -1 and column == -1:
column = 0

# padding is only allowed when center option is false
if padding and not center:
pad = self.columns - len(text)
text = text + (" " * pad)

# center text
if center:
pad = self.columns - len(text)
leftPad = pad // 2
rightPad = pad - leftPad
text = (" " * leftPad) + text + (" " * rightPad)

if row != -1:
self.setLcdCursor(row, column)

self._lcd.write_string(text)


def turnOffBacklight(self):
self._lcd.backlight_enabled = False


def turnOnBacklight(self):
self._lcd.backlight_enabled = True
219 changes: 219 additions & 0 deletions Script/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
from datetime import datetime
import time

from lcd20x4 import Lcd20x4
from rpigpio import RpiGpio

from utility import *
from common import *
from pinDescription import *


# global hardware module library initilization
lcd = Lcd20x4(LCD_MODULE_ADDRESS, LCD_MODULE_NO_OF_COLUMN, LCD_MODULE_NO_OF_ROW)
gpio = RpiGpio()


# global variables
cycleIndexPos = 0
cycleCounter = 0

previousPosition = None
currentPosition = None

ResetBtnReading = None
buttonState = None

powerDownTrigger = False
ResetTrigger = False
isEepromReadNeed = True
cycleIndexPosMiddle = False

lastButtonState = HIGH
debounceDelay = 5000
lastDebounceTime = 0


# Introduction banner print
def startIntroPrint():
lcd.write("SPRING LOADED", row = ROW_NO_0, center = True)
lcd.write("SWITCH TESTER", row = ROW_NO_1, center = True)
appVersion = getAppVersion()
lcd.write(f"Version: {appVersion}", row = ROW_NO_3, padding = True)
time.sleep(3)
lcd.clean()
time.sleep(0.5)
lcd.turnOffBacklight()
time.sleep(1)
lcd.turnOnBacklight()
time.sleep(1)


# This is the gpio initlization
def gpioInilitization():
gpio.pinMode(ON_BOARD_LED_PIN, OUTPUT)

gpio.pinMode(MICRO_SWITCH_S1_NC_PIN, INPUT)
gpio.pinMode(MICRO_SWITCH_S1_NO_PIN, INPUT)
gpio.pinMode(MICRO_SWITCH_S2_NC_PIN, INPUT)
gpio.pinMode(MICRO_SWITCH_S2_NO_PIN, INPUT)

gpio.pinMode(POWER_LINE_DETECT_PIN, INPUT)
gpio.pinMode(RESET_PUSH_SWITCH_PIN, INPUT)

gpio.pinMode(ON_BOARD_LED_PIN, OUTPUT)


# Time print function
def printCurrentTime(row: int):
lcd.write(datetime.now().strftime('%I:%M:%S %p %d/%m/%y'), row = ROW_NO_0, padding = True)
# time.sleep(0.1)


# Print the count value
def printCount(row: int, count: int):
lcd.write(f"Count: {count}", row = row, padding = True)


# This is the void setup() function just like Arduino code
def setup():
global cycleIndexPos
global previousPosition
global cycleCounter

startIntroPrint()
gpioInilitization()
createRtDbFile()

if gpio.digitalRead(MICRO_SWITCH_S1_NO_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NC_PIN):
previousPosition = POSITION_LEFT
cycleIndexPos = POSITION_LEFT

if gpio.digitalRead(MICRO_SWITCH_S1_NC_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NC_PIN):
previousPosition = POSITION_MIDDLE
cycleIndexPos = POSITION_MIDDLE

if gpio.digitalRead(MICRO_SWITCH_S1_NC_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NO_PIN):
previousPosition = POSITION_RIGHT
cycleIndexPos = POSITION_RIGHT

########## TEST BEGIN ###############
if gpio.digitalRead(MICRO_SWITCH_S1_NO_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NC_PIN) and\
gpio.digitalRead(MICRO_SWITCH_S1_NC_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NC_PIN) and\
gpio.digitalRead(MICRO_SWITCH_S1_NC_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NO_PIN):
previousPosition = POSITION_MIDDLE
cycleIndexPos = POSITION_MIDDLE
print("Probably No switch found; All pin are HIGH ... !!")
########## TEST END## ###############

cycleCounter = getCycleCount()
printCount(row = ROW_NO_2, count = cycleCounter)

gpio.digitalWrite(ON_BOARD_LED_PIN, LOW)


# This is the void loop() function just like Arduino code
def loop():
global powerDownTrigger
global isEepromReadNeed
global previousPosition
global cycleIndexPos
global currentPosition
global cycleCounter
global cycleIndexPosMiddle
global ResetBtnReading
global lastButtonState
global debounceDelay
global buttonState
global ResetTrigger
global lastDebounceTime

while True:
if not powerDownTrigger:
printCurrentTime(ROW_NO_0)

# If power down condition happend
if gpio.digitalRead(POWER_LINE_DETECT_PIN) == LOW:
lcd.turnOffBacklight()
lcd.clean()
powerDownTrigger = True

if not isEepromReadNeed:
setCycleCount(cycleCounter)
isEepromReadNeed = True
continue
else:
lcd.turnOnBacklight()
powerDownTrigger = False
if isEepromReadNeed:
cycleCounter = getCycleCount()
lcd.write(" "*LCD_MODULE_NO_OF_COLUMN, row = ROW_NO_3)
isEepromReadNeed = False

# Reading the gpio pin for the switchs
if gpio.digitalRead(MICRO_SWITCH_S1_NO_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NC_PIN):
currentPosition = POSITION_LEFT
lcd.write("Position Left ", row = ROW_NO_1)

if gpio.digitalRead(MICRO_SWITCH_S1_NC_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NC_PIN):
currentPosition = POSITION_MIDDLE
lcd.write("Position Middle", row = ROW_NO_1)

if gpio.digitalRead(MICRO_SWITCH_S1_NC_PIN) and gpio.digitalRead(MICRO_SWITCH_S2_NO_PIN):
currentPosition = POSITION_RIGHT
lcd.write("Position Right ", row = ROW_NO_1)

# According to the position, update the count number
if currentPosition != previousPosition:
if currentPosition == POSITION_LEFT or POSITION_LEFT == POSITION_RIGHT:
if cycleIndexPos == currentPosition:
cycleCounter += 1
elif currentPosition == POSITION_MIDDLE:
if cycleIndexPosMiddle and (cycleIndexPos == currentPosition):
cycleCounter += 1
cycleIndexPosMiddle = not cycleIndexPosMiddle
else:
pass

# Update the count in the LCD
previousPosition = currentPosition
printCount(row = ROW_NO_2, count = cycleCounter)

# If reach the full count number then turn on the Finish LED
if cycleCounter >= 7500000:
gpio.digitalWrite(ON_BOARD_LED_PIN, HIGH)
cycleCounter = 0

# Reset button debounce logic
ResetBtnReading = gpio.digitalRead(RESET_PUSH_SWITCH_PIN)

if ResetBtnReading != lastButtonState:
lastDebounceTime = time.time()

if ((time.time() - lastDebounceTime) * 1000) > debounceDelay:
if ResetBtnReading != buttonState:
buttonState = ResetBtnReading

if buttonState == LOW:
lcd.write("Count Reseting... ", row = ROW_NO_3)
ResetTrigger = True

lastButtonState = ResetBtnReading

# If reset button pressed then clean the old stuffs
if ResetTrigger:
cycleCounter = 0
setCycleCount(cycleCounter)
ResetTrigger = False
time.sleep(2)
lcd.write(" "*LCD_MODULE_NO_OF_COLUMN, row = ROW_NO_3)


# Entry point main function
def main():
setup()
loop()


if __name__ == "__main__":
main()
12 changes: 12 additions & 0 deletions Script/pinDescription.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
MICRO_SWITCH_S1_NO_PIN = 17
MICRO_SWITCH_S1_NC_PIN = 27
MICRO_SWITCH_S2_NO_PIN = 22
MICRO_SWITCH_S2_NC_PIN = 18

RESET_PUSH_SWITCH_PIN = 23

ON_BOARD_LED_PIN = 24

POWER_LINE_DETECT_PIN = 25

LCD_MODULE_ADDRESS = 0x27
60 changes: 60 additions & 0 deletions Script/rpigpio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import RPi.GPIO as GPIO
from common import *

class RpiGpio:
def __init__(self):
self.init()


def init(self):
GPIO.setmode(GPIO.BCM)


def deinit(self):
GPIO.cleanup()


def pinMode(self, pin: int, state: bool, pullUpDown: bool = None):
_state = None
_pullUpDown = None

# Mapping with INPUT OUTPUT macro with GPIO.IN GPIO.OUT
if state == INPUT:
_state = GPIO.IN
elif state == OUTPUT:
_state = GPIO.OUT
else:
raise Exception("Wrong pin status!!")

# Mapping with PULL_UP PULL_DOWN macro with GPIO.PUD_UP GPIO.PUD_DOWN
if pullUpDown == PULL_UP:
_pullUpDown = GPIO.PUD_UP
elif pullUpDown == PULL_DOWN:
_pullUpDown = GPIO.PUD_DOWN
else:
_pullUpDown = GPIO.PUD_OFF

if pullUpDown != None:
GPIO.setup(pin, _state, pull_up_down = _pullUpDown)
else:
GPIO.setup(pin, _state)


def digitalRead(self, pin: int):
state = GPIO.input(pin)
return state


def digitalWrite(self, pin: int, state: bool):
_state = None

# Mapping with INPUT OUTPUT macro with GPIO.IN GPIO.OUT
if state == INPUT:
_state = GPIO.IN
elif state == OUTPUT:
_state = GPIO.OUT
else:
raise Exception("Wrong pin status!!")

GPIO.output(pin, _state)

Loading