chaosjester
Posts: 4
Joined: Sat Mar 24, 2018 8:57 am

Manufacturing cycle timer

Wed Feb 01, 2023 4:54 am

Hi All,

I have been asked if it would be possible roll out a manufacturing cycle timer based off a Pi, either full Pi, zero or if possible a pico would be awesome.

I am fairly well versed with using a Pi for more simple things like media servers, gaming and desktop use so this is a bit out of my wheelhouse.

What has been asked is for multiple displays that could display a countdown timer, with the following requirements:
Repeating 1 hour countdown, once reached play a sound then restart counting down from an hour
Start timer automatically at start of the day, stop automatically at the end of the day. Same times Mon-Thu but different times on a Friday
Pause the timer during break times, same times each day

While I know this would be 100% acheivable, really not too sure what kind of software I should be looking at to drive it.

I've never really done any python etc so would love if there is a framework I could use to make this easier. We do use Node Red in the environment to set off our break time horns, but that was put together by a 3rd party and I know just enough about it to keep it alive.

Would anyone be able to suggest any good starting points for this kind of project?

TIA

ame
Posts: 6698
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: Manufacturing cycle timer

Wed Feb 01, 2023 5:03 am

chaosjester wrote:
Wed Feb 01, 2023 4:54 am

Would anyone be able to suggest any good starting points for this kind of project?

TIA
Pencil and paper. Write down precisely how the system will behave, try to anticipate as many potential errors and failures, and how you might recover from them. Then write down what kind of hardware you might need and how it goes together.

It's easy to get some gear and have a go, but if you haven't done anything like this before it's better to think about it in some detail first.

Most of the software design should fall out of the written description, so you will know what to do (although not necessarily how to do it).

It actually sounds pretty simple, but watch out for feature-creep. Build what you described here first, then think about adding new things.

Good luck.
Hmm. What can I put here?

gordon77
Posts: 7139
Joined: Sun Aug 05, 2012 3:12 pm

Re: Manufacturing cycle timer

Wed Feb 01, 2023 8:19 am

Here's a starter...

put your mp3 sound file in your home directory

Updated : Times now hr:mins, will now work if no sound file found

If you want fullscreen use windowSurfaceObj = pygame.display.set_mode((width,height),pygame.FULLSCREEN)

Code: Select all

#!/usr/bin/python3
import RPi.GPIO as GPIO
import pygame, sys
import time
from pygame.locals import *
import datetime
from pygame import mixer
import os

# set timer
timer_time = 3600 # seconds

# sound file
sound_file = "horn.mp3"

# set daily hours 
#              [  Mon,   Tues,   Weds,   Thurs,  Fri,    Sat,     Sun  ]
start_times  = ['08:30','08:30','08:30','08:30','09:00','09:00','10:00']
end_times    = ['17:00','17:00','18:00','17:00','17:00','16:00','16:00']

# set break times
#              [break1 ,break2, break3 ] 
break_starts = ['10:00','12:00','15:00']
break_ends   = ['10:15','13:00','15:15']

# setup display
greenColor = pygame.Color(0,255,0)
greyColor  = pygame.Color(100,100,100)
blackColor = pygame.Color(0,0,0)
pygame.init()
font = 200
width = font * 4
height = font
windowSurfaceObj = pygame.display.set_mode((width,height),1) # pygame.FULLSCREEN)
pygame.display.set_caption('TIMER')
fontObj = pygame.font.Font('freesansbold.ttf',font)

# setup sound
if os.path.exists(sound_file):
    mixer.init()
    mixer.music.load(sound_file) # ensure mp3 file in home directory
    mixer.music.set_volume(0.9)

def display(color):
    global w,width,height,blackColor,greyColor
    # calculate h,m,s
    m,s = divmod(w,60)
    h,m = divmod(m,60)
    # Display
    msg = "%02d:%02d:%02d" % (h,m,s)
    pygame.draw.rect(windowSurfaceObj,blackColor,Rect(0,0,width,height))
    if w == 0:
        msgSurfaceObj = fontObj.render(msg, False,color)
    else:
        msgSurfaceObj = fontObj.render(msg, False,color)
    msgRectobj = msgSurfaceObj.get_rect()
    msgRectobj.topleft =(12,0)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
    windowSurfaceObj.blit(msgSurfaceObj, msgRectobj)
    pygame.display.update()
    
w = 0
display(greyColor)

try:
    while True:
        time.sleep(0.2)
        # get current datetime
        now = datetime.datetime.now()
        # get day of week as an integer
        day = now.isoweekday()
        # get start, end and break times for today
        start_time   = int(start_times[day - 1][0:2]) + int(start_times[day - 1][3:5])/60
        end_time     = int(end_times[day - 1][0:2]) + int(end_times[day - 1][3:5])/60
        break_start1 = int(break_starts[0][0:2]) + int(break_starts[0][3:5])/60
        break_end1   = int(break_ends[0][0:2]) + int(break_ends[0][3:5])/60
        break_start2 = int(break_starts[1][0:2]) + int(break_starts[1][3:5])/60
        break_end2   = int(break_ends[1][0:2]) + int(break_ends[1][3:5])/60
        break_start3 = int(break_starts[2][0:2]) + int(break_starts[2][3:5])/60
        break_end3   = int(break_ends[2][0:2]) + int(break_ends[2][3:5])/60
        # check it's working hours
        h = int(str(datetime.datetime.now().hour))
        m = int(str(datetime.datetime.now().minute))
        s = int(str(datetime.datetime.now().second))
        t = h + (m/60) + (s/3600)
        if t >= start_time and t <= end_time:
            start = time.time()
            run = 1
            while run == 1 and t <= end_time and (t <= break_start1 or t >= break_end1) and (t <= break_start2 or t >= break_end2) and (t <= break_start3 or t >= break_end3):
                time.sleep(0.1)
                w = timer_time - (time.time() - start)
                # check it's still working hours
                h = int(str(datetime.datetime.now().hour))
                m = int(str(datetime.datetime.now().minute))
                s = int(str(datetime.datetime.now().second))
                t = h + (m/60) + (s/3600)
                # time out
                if w < 0:
                    # play sound
                    if os.path.exists(sound_file):
                        mixer.music.play()
                    run = 0
                # display timer
                display(greenColor)
                # quit
                for event in pygame.event.get():
                    if event.type == QUIT or event.type == MOUSEBUTTONUP or event.type == KEYDOWN:
                        pygame.quit()
                        sys.exit()
            w = 0
            display(greyColor)
        else:
            w = 0
            display(greyColor)
            # quit
            for event in pygame.event.get():
                if event.type == QUIT or event.type == MOUSEBUTTONUP or event.type == KEYDOWN:
                    pygame.quit()
                    sys.exit()
except KeyboardInterrupt:
  print ("  Quit")
  GPIO.cleanup()
  pygame.quit()
  sys.exit()
Last edited by gordon77 on Thu Feb 02, 2023 2:16 pm, edited 4 times in total.

chaosjester
Posts: 4
Joined: Sat Mar 24, 2018 8:57 am

Re: Manufacturing cycle timer

Wed Feb 01, 2023 8:17 pm

ame wrote:
Wed Feb 01, 2023 5:03 am
Pencil and paper. Write down precisely how the system will behave, try to anticipate as many potential errors and failures, and how you might recover from them. Then write down what kind of hardware you might need and how it goes together.

It's easy to get some gear and have a go, but if you haven't done anything like this before it's better to think about it in some detail first.

Most of the software design should fall out of the written description, so you will know what to do (although not necessarily how to do it).

It actually sounds pretty simple, but watch out for feature-creep. Build what you described here first, then think about adding new things.

Good luck.
Good advise, there are a few commercial products that do takt/cycle timing with things like actual vs predicted production etc so with the current brief that sort of thing isn't covered but if I mention these they will probably want that kind of thing. At that point, I would suggest going for the commercial product rather than a janky thing thrown together by the IT guy :lol:
gordon77 wrote: Here's a starter...

put your mp3 sound file in your home directory
Many thanks for that, will have a play around with that. I am a PowerShell guy and never really dabbled in python but can see where you are going with that and it looks good. Much appreciated :D

Return to “Other projects”