Callback for ringing, CLI and SMS added. Tidied turn on and command processes for better asynchronous startup.
parent
655af11946
commit
41a2fa37dd
|
@ -1,19 +1,26 @@
|
|||
import machine
|
||||
import time
|
||||
import micropython
|
||||
|
||||
CALLER_CALLBACK = 1
|
||||
CLI_CALLBACK = 2
|
||||
NEWSMS_CALLBACK = 3
|
||||
|
||||
uart_port = 1
|
||||
uart_default_baud = 115200
|
||||
uart_timeout = 28
|
||||
default_response_timeout = 2000
|
||||
|
||||
status_pin = machine.Pin(6, machine.Pin.IN)
|
||||
ringer_pin = machine.Pin(8, machine.Pin.IN)
|
||||
pwr_key_pin = machine.Pin(23, machine.Pin.OUT)
|
||||
status_pin = machine.Pin(machine.Pin.GPIO_SIM_STATUS, machine.Pin.IN)
|
||||
ringer_pin = machine.Pin(machine.Pin.GPIO_SIM_RI, machine.Pin.IN)
|
||||
pwr_key_pin = machine.Pin(machine.Pin.GPIO_SIM_PWR_KEY, machine.Pin.OUT)
|
||||
|
||||
# Open the UART
|
||||
uart = machine.UART(uart_port, uart_default_baud, mode=machine.UART.BINARY, timeout=uart_timeout)
|
||||
dirtybuffer = False # Flag if the buffer could have residual end of reresponsesponces line in it?
|
||||
|
||||
callbacks = []
|
||||
|
||||
# Check if the SIM800 is powered up
|
||||
def ison():
|
||||
return status_pin.value()==1
|
||||
|
@ -22,6 +29,22 @@ def ison():
|
|||
def isringing():
|
||||
return ringer_pin.value()==0
|
||||
|
||||
# Register for a callback
|
||||
def registercallback(call, function):
|
||||
callbacks.append([call, function])
|
||||
|
||||
# Deregitser for a callback
|
||||
def deregistercallback(function):
|
||||
for entry in callbacks:
|
||||
if entry[1]==function:
|
||||
callbacks.remove(entry)
|
||||
|
||||
# Execute external funtion of a callback
|
||||
def callcallback(call, parameter):
|
||||
for entry in callbacks:
|
||||
if entry[0]==call:
|
||||
micropython.schedule(entry[1], parameter)
|
||||
|
||||
# Identify if this was a positive response
|
||||
def ispositive(response):
|
||||
return (response=="OK") or response.startswith("CONNECT") or response.startswith("SEND OK")
|
||||
|
@ -68,16 +91,31 @@ def readline():
|
|||
elif not (charin == b'\n'):
|
||||
stringin += str(charin, "ASCII")
|
||||
|
||||
def processcallbacks(line):
|
||||
# Check for ringing
|
||||
if line=="RING":
|
||||
callcallback(CALLER_CALLBACK, "")
|
||||
# Check for new caler lin identification
|
||||
val = extractval("+CLIP:", [line])
|
||||
if val:
|
||||
callcallback(CLI_CALLBACK, val)
|
||||
# Check for new SMS messages
|
||||
val = extractval("+CMT:", [line])
|
||||
if val:
|
||||
callcallback(NEWSMS_CALLBACK, val)
|
||||
|
||||
# Process the buffer for unsolicited result codes
|
||||
def processbuffer():
|
||||
while uart.any()>0:
|
||||
line = readline()
|
||||
processcallbacks(line)
|
||||
|
||||
# Execute a command on the module
|
||||
# command is the AT command without the AT or CR/LF, response_timeout (in ms) is how long to wait for completion, required_response is to wait for a non standard response, custom_endofdata will finish when found
|
||||
def command(command="AT", response_timeout=default_response_timeout, required_response=None, custom_endofdata=None):
|
||||
# The same interface as and called by command() but without power so can be called from power()
|
||||
def command_internal(command="AT", response_timeout=default_response_timeout, required_response=None, custom_endofdata=None):
|
||||
global dirtybuffer
|
||||
# Empty the buffer
|
||||
uart.read()
|
||||
# Do not bother if we are powered off
|
||||
if not ison():
|
||||
dirtybuffer = False
|
||||
return ["POWERED OFF"]
|
||||
# Process anything remaining in the buffer
|
||||
processbuffer()
|
||||
# Send the command
|
||||
uart.write(command + "\r")
|
||||
# Read the results
|
||||
|
@ -87,6 +125,7 @@ def command(command="AT", response_timeout=default_response_timeout, required_re
|
|||
timeouttime = time.time()+(response_timeout/1000)
|
||||
while (time.time()<timeouttime):
|
||||
line = readline()
|
||||
processcallbacks(line)
|
||||
# Remember the line if not empty
|
||||
if (len(line)>0):
|
||||
result.append(line)
|
||||
|
@ -123,20 +162,25 @@ def power(onoroff, async):
|
|||
# Stop pressing the virtual key
|
||||
pwr_key_pin.off()
|
||||
# Clear the buffer
|
||||
uart.read()
|
||||
processbuffer()
|
||||
dirtybuffer = False
|
||||
# Send a command to autonigotiate UART speed
|
||||
# We are now live
|
||||
if isonnow:
|
||||
command("AT")
|
||||
# Send a command to autonigotiate UART speed
|
||||
command_internal("AT")
|
||||
# Turn on new SMS notificationn
|
||||
command_internal("AT+CNMI=1,2")
|
||||
# Turn on calling line identification notification
|
||||
command_internal("AT+CLIP=1")
|
||||
return isonnow
|
||||
|
||||
# Power on the SIM800 (returns true when on)
|
||||
def poweron(async=False):
|
||||
power(True, async)
|
||||
return power(True, async)
|
||||
|
||||
# Power off the SIM800
|
||||
def poweroff(async=False):
|
||||
power(False, async)
|
||||
return power(False, async)
|
||||
|
||||
# Change the speed on the communication
|
||||
def uartspeed(newbaud):
|
||||
|
@ -148,6 +192,13 @@ def uartspeed(newbaud):
|
|||
else:
|
||||
uart = machine.UART(uart_port, newbaud, mode=UART.BINARY, timeout=uart_timeout)
|
||||
|
||||
# command is the AT command without the AT or CR/LF, response_timeout (in ms) is how long to wait for completion, required_response is to wait for a non standard response, custom_endofdata will finish when found
|
||||
def command(command="AT", response_timeout=default_response_timeout, required_response=None, custom_endofdata=None):
|
||||
# Check we are powered on and set up
|
||||
poweron(False)
|
||||
# Call the internal command() function
|
||||
return command_internal(command, response_timeout, required_response, custom_endofdata)
|
||||
|
||||
# Make a voice call
|
||||
def call(number):
|
||||
command("ATD" + str(number) + ";", 20000)
|
||||
|
@ -550,9 +601,12 @@ def fsmv(filenamefrom, filenameto):
|
|||
|
||||
|
||||
# Start turning on the SIM800
|
||||
poweron(True)
|
||||
onatstart = poweron(True)
|
||||
|
||||
# Testing code to move to app
|
||||
# Try using call and end buttons to answer and hangup
|
||||
#tilda.Buttons.enable_interrupt(tilda.Buttons.BTN_Call, answer())
|
||||
#tilda.Buttons.enable_interrupt(tilda.Buttons.BTN_End, hangup())
|
||||
|
||||
# See if the netowrk list can be used for checking SIM800
|
||||
#status_pin = machine.Pin(7, machine.Pin.IN)
|
||||
#tilda.Buttons.enable_interrupt(machine.Pin(machine.Pin.GPIO_SIM_NETLIGHT, machine.Pin.IN),processbuffer())
|
||||
|
|
Loading…
Reference in New Issue