Software

Sensing

In order for Meat Master to take the reading of the protein that it is cooking, we were using a thermocouple. I opted to take 20 samples of the temperature and take the average. This was done to make the readings that the thermocouple were outputting to be more consistent. When testing, we noticed that the fluctuations in temperature could be quite large and would trigger the done sequence to start prematurely.

Additionally, we have a timer that is running to let the user know when it is time to flip the protein.

Code
therm_sum = 0.0
therm_reading = []
# Take Samples
for k in range(20):
    therm_reading.append(adc0.read())
    therm_sum += therm_reading[k]
# Average Samples - calibration offset
therm_avg = (((therm_sum / 20000) - 1.25) / 0.005) - 0
print(" T = %3.3f deg C" % (therm_avg))

Communication

To start Meat Master, the user would send a message to let it know what it is cooking and the doneness that the user wishes to achieve. Master would then interpret the message and choose the appropriate temperatures.

Code
# Define callback function to retrieve the message
temp = 0
message = ''
def sub_cb(topic, msg):
    global message
    global temp
    message = msg.decode()
    if "BEEF" in message:
        if "MEDIUM-RARE" in message:
            temp = 52
        elif "MEDIUM-WELL" in message:
            temp = 62
        elif "RARE" in message:
            temp = 49
        elif "MEDIUM" in message:
            temp = 55
        else:
            temp = 64
    elif "CHICKEN" in message:
        if "MEDIUM-WELL"  in message:
            temp = 62
        elif "MEDIUM" in message:
            temp = 57
        else:
            temp = 75
    print(temp)
    print(message)

When the thermocouple determines that the protein should be either be flipped or is done cooking, Meat Master moves communication. Meat master has two methods of communication: Text and music.

Text is used to notify the user in the event that they walk away from the stovetop to do something else meanwhile.

Code
    if therm_avg >= temp:
        L1.duty(50)
        print("Sent Done to AdaFruit")
        mqtt.publish(feedName_done, sendDone)
        print("Published {} to {}.".format(sendDone, feedName_done))
        # Play Finish Sound
        t1.init(period=75, mode=t1.PERIODIC, callback=grand_finale)
        done = 1
    elif flip_time == 0:
        L1.duty(50)
        print("Sent Flip to Adafruit")
        mqtt.publish(feedName_flip, sendFlip)
        print("Published {} to {}.".format(sendFlip, feedName_flip))
        flip_time = 30
        # Play Flip Sound
        t1.init(period=10, mode=t1.PERIODIC, callback=annoying_flip_sound)

Furthermore if the user does not have their phone, they could hear Meat Master playing a sound to let them know that it is done cooking. There are two different sounds that are played to let the user know which action should be done.

Flip Sound
def annoying_flip_sound(timer):
    print("BETTER FLIP IT")
    global start
    global note
    note = annoying_freq[start]
    print(note)
    L1.freq(note)
    if start < len(annoying_freq)-1:
        start += 1
    else:
        L1.duty(0)
        t1.deinit()
Finish Sound
def grand_finale(timer):
    print("PLAY THE FINALE")
    global note
    global start
    note = tchaikovsky[start]
    print(note)
    L1.freq(note)
    if start < len(tchaikovsky)-1:
        start += 1
    else:
        start = 0

Full Code

Code
from mqttclient import MQTTClient
from machine import Pin, ADC, Timer, PWM
import network 
from board import ADC0
import sys
import time
import math

# Timers
t1 = Timer(0) # Play Music

# Set up Thermoprobe Amp
adc0 = ADC(Pin(ADC0)) # Pin A4
adc0.atten(ADC.ATTN_6DB) # max reading = 1.8V

# Check wifi connection
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
ip = wlan.ifconfig()[0]
if ip == '0.0.0.0':
    print("no wifi connection")
    sys.exit()
else:
    print("connected to WiFi at IP", ip)

# Set up Adafruit connection
adafruitIoUrl = 'io.adafruit.com'
adafruitUsername = 'chrisx'
adafruitAioKey = 'aio_KtmR98ivJWkH9FizfmF2fu0Pesxz'

# Define callback function to retrieve the message
temp = 0
message = ''
def sub_cb(topic, msg):
    global message
    global temp
    message = msg.decode()
    if "BEEF" in message:
        if "MEDIUM-RARE" in message:
            temp = 52
        elif "MEDIUM-WELL" in message:
            temp = 62
        elif "RARE" in message:
            temp = 49
        elif "MEDIUM" in message:
            temp = 55
        else:
            temp = 64
    elif "CHICKEN" in message:
        if "MEDIUM-WELL"  in message:
            temp = 62
        elif "MEDIUM" in message:
            temp = 57
        else:
            temp = 75
    print(temp)
    print(message)

# Connect to Adafruit server
print("Connecting to Adafruit")
mqtt = MQTTClient(adafruitIoUrl, port='1883', user=adafruitUsername, password=adafruitAioKey)
time.sleep(0.5)
print("Connected!")

# Send test message
feedName_done = "chrisx/feeds/done-cooking"
feedName_flip = "chrisx/feeds/time-flip"
feedName_email = "chrisx/feeds/emails"
sendDone = "done"
sendFlip = "flip"

# This will set the function sub_cb to be called when mqtt.check_msg() checks
# that there is a message pending
mqtt.set_callback(sub_cb)
mqtt.subscribe(feedName_email)

# All the notes
C3 = 131 
CS3 = 139 
D3 = 147 
DS3 = 156 
E3 = 165 
F3 = 175 
FS3 = 185 
G3 = 196 
GS3 = 208 
A3 = 220 
AS3 = 233 
B3 = 247 
C4 = 262 
CS4 = 277 
D4 = 294 
DS4 = 311 
E4 = 330 
F4 = 349 
FS4 = 370 
G4 = 392 
GS4 = 415 
A4 = 440 
AS4 = 466 
B4 = 494 
C5 = 523 
CS5 = 554 
D5 = 587 
DS5 = 622 
E5 = 659 
F5 = 698 
FS5 = 740 
G5 = 784 
GS5 = 831 
A5 = 880 
AS5 = 932 
B5 = 988 
C6 = 1047 
CS6 = 1109 
D6 = 1175 
DS6 = 1245 
E6 = 1319 
F6 = 1397 
FS6 = 1480 
G6 = 1568 
GS6 = 1661 
A6 = 1760 
AS6 = 1865 
B6 = 1976 
C7 = 2093 
CS7 = 2217 
D7 = 2349 
DS7 = 2489 
E7 = 2637 
F7 = 2794 
FS7 = 2960 
G7 = 3136 
GS7 = 3322 
A7 = 3520 
AS7 = 3729 
B7 = 3951 
C8 = 4186 
CS8 = 4435 
D8 = 4699 
DS8 = 4978 
# Define Sound Arrays
tchaikovsky = [
    AS4,9999,AS4,DS5,DS5,F5,F5,G5,G5,F5,F5,DS5,DS5,F5,F5,G5,G5,9999,9999,DS5,DS5,9999,9999,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,
    AS4,9999,AS4,DS5,DS5,F5,F5,G5,G5,F5,F5,DS5,DS5,F5,F5,G5,G5,9999,9999,DS5,DS5,9999,9999,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,
    9999,9999,C5,9999,C5,F5,F5,G5,G5,F5,F5,C5,C5,GS4,GS4,C5,C5,F5,F5,C5,C5,GS4,GS4,C5,C5,F5,F5,F5,F5,F5,F5,F5,F5,
    AS4,9999,AS4,DS5,DS5,F5,F5,G5,G5,F5,F5,DS5,DS5,F5,F5,G5,G5,9999,9999,DS5,DS5,9999,9999,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,
    AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,C5,C5,C5,C5,C5,C5,C5,C5,9999,C5,C5,C5,C5,C5,C5,C5,C5,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,G4,G4,G4,G4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,DS4,
    DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,DS5,D5,D5,D5,D5,D5,D5,D5,D5,C5,C5,C5,C5,C5,C5,C5,C5,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,
    C5,C5,C5,C5,C5,C5,C5,C5,C5,C5,C5,C5,C5,C5,C5,C5,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,
    AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,9999,AS4,AS4,AS4,AS4,AS4,AS4,AS4,AS4,G4,G4,G4,G4,G4,G4,G4,G4,G4,G4,G4,G4,GS4,GS4,GS4,GS4,A4,A4,A4,A4,AS4,AS4,AS4,AS4,B4,B4,B4,B4,C5,C5,C5,C5,
    AS5,AS5,AS5,A5,A5,A5,GS5,GS5,GS5,G5,G5,G5,FS5,FS5,FS5,F5,F5,F5,E5,E5,E5,DS5,DS5,DS5,D5,D5,D5,CS5,CS5,CS5,C5,C5,C5,B4,B4,B4,AS4,AS4,9999,9999,B4,B4,9999,9999,C5,C5,9999,9999,D5,D5,DS5,DS5
]
freq_start = [1000] * 501
# Create Array full of annoying frequencies
for i in range(1,501):
    freq_start[i] = freq_start[0] + i
reverse_freq = freq_start[::-1]
annoying_freq = freq_start + reverse_freq

# Speaker = Pin(LED, mode=Pin.OUT)
start = 0
speaker_ext = Pin(27, mode=Pin.OUT)
L1 = PWM(speaker_ext,freq=1,duty=0,timer=0)

# Play Speaker Sounds
def annoying_flip_sound(timer):
    print("BETTER FLIP IT")
    global start
    global note
    note = annoying_freq[start]
    print(note)
    L1.freq(note)
    if start < len(annoying_freq)-1:
        start += 1
    else:
        L1.duty(0)
        t1.deinit()

def grand_finale(timer):
    print("PLAY THE FINALE")
    global note
    global start
    note = tchaikovsky[start]
    print(note)
    L1.freq(note)
    if start < len(tchaikovsky)-1:
        start += 1
    else:
        start = 0

# Look for messages (e.g. from the Adafruit Toggle block) on your test feed:
done = 0
while temp == 0:
    chk = mqtt.check_msg()
    time.sleep(1)
print("Exit Message Retrieval")

# Define temperature sensing & timer checking
flip_time = 60
while done == 0:
    time.sleep(1)
    flip_time = flip_time - 1
    therm_sum = 0.0
    therm_reading = []
    for k in range(20):
        therm_reading.append(adc0.read())
        therm_sum += therm_reading[k]
    therm_avg = (((therm_sum / 20000) - 1.25) / 0.005) - 0
    print(" T = %3.3f deg C" % (therm_avg))
    if therm_avg >= temp:
        L1.duty(50)
        print("Sent Done to AdaFruit")
        mqtt.publish(feedName_done, sendDone)
        print("Published {} to {}.".format(sendDone, feedName_done))
        t1.init(period=75, mode=t1.PERIODIC, callback=grand_finale)
        done = 1
    elif flip_time == 0:
        L1.duty(50)
        print("Sent Flip to Adafruit")
        mqtt.publish(feedName_flip, sendFlip)
        print("Published {} to {}.".format(sendFlip, feedName_flip))
        flip_time = 30
        t1.init(period=10, mode=t1.PERIODIC, callback=annoying_flip_sound)

Last updated