Modifying the code

To start with this activity, we have provided a working template on the Edison_Bluetooth repository. You can now open and edit it to adjust the code to your hardware configuration and add more functionality to your application.

First of all, we will uncomment an import line in spp.py that help us run our main code correctly. Do the following:

root@edison # cd
root@edison # cd Edison_Bluetooth/projects/hospital-assistant/
root@edison # nano spp.py
...

Once opened, go to line 13 and erase the pound sign "#". Save your changes and exit. (Ctrl + X, Y, and [ENTER].

To continue and open it use the following commands:

root@edison # cd
root@edison # cd Edison_Bluetooth/projects/hospital-assistant/
root@edison # nano hospital-assistant.py

To save your changes press Ctrl-C and then [Enter] to confirm the file name.

To exit from the nano editor press Ctrl-X.

Completed example

In addition to the project template, you will find a completed example file in the same directory that you might use as a reference to add more functionality to your program.

To open it on your terminal, from the hospital-assistant directory use the following command:

root@edison # nano example.py

The following is a brief description of the main sections and functions you will find on it:

Import Section

The main purpose of this section is to import the needed Python modules.

#!/usr/bin/python
from threading import Timer

import pyupm_grove as grove
import pyupm_i2clcd as lcd
import pyupm_ttp223 as ttp

For this example, we don't need to modify it.

Configuration Values

These values are used later in the code to configure the pins employed by the different Grove kit components, and to set other configurations, like the LCD background color, the pill timer limit or the messages returned to the Bluetooth host.

# Pins used in Grove kit.
PILL_BUTTON = 2
EMERGENCY_BUTTON = 3
ALERT_LED = 4

# Configuration values.
PILL_TIMER_LIMIT = 5    # in seconds
LCD_BACKGROUND_COLOR = (50, 50, 100)  # in RGB decimal values
LCD_BACKGROUND_ALERT_COLOR = (255, 0, 0)    # in RGB decimal values

# Alarm status.
ON = True
OFF = False
alarm_status_list = {ON: "on",
                     OFF: "off"}

# Succes code for Bluetooth commands.
SUCCESS_CODE = "OK"

You'll need to adjust these values to match the pins and behavior you look for your device.

Initialization

In this section, the devices are initialized according to the configuration values set on the previous section. In addition, the variables used as flags and containers are defined and set to their default values.

# Initialize your devices.
display = lcd.Jhd1313m1(0, 0x3E, 0x62)
alarm_led = grove.GroveLed(ALERT_LED)
pill_button = grove.GroveButton(PILL_BUTTON)
emergency_button = ttp.TTP223(EMERGENCY_BUTTON)

# Initialize variables.
initialized = False
pill_counter = 0
pill_is_due = False
pill_button_released = True
emergency_button_released = True
alarm_status = OFF
timer = None

Functions

In this part, all of the functions that execute each task in the program are defined. They can be grouped in the following way:

  • LCD: The objective of functions in this section is to set the color and clear the LCD, and display the required messages to the user.

    def displayInit(color):
      display.setColor(*color)
      display.clear()
    
    def displayMessage(message, line, pos=0):
      display.setCursor(line, pos)
      display.write(message)  
    
    def updateDisplay():
      if not pill_is_due:
          displayInit(LCD_BACKGROUND_COLOR)
      else:
          displayInit(LCD_BACKGROUND_ALERT_COLOR)
      displayMessage("Pills taken: %s" % str(pill_counter), 0, 0)
      if pill_is_due:
          displayMessage("*ADMINISTER PILL", 1, 0)
    
  • Pill Administration: In this code block there are the functions used to set and restart the timer for pill administration, and to increase or reset the administrated pill counter.

      def administerPill():
          global pill_counter
          pill_counter += 1
          setNextPillTimer()
          updateDisplay()
          return str(SUCCESS_CODE)
    
      def resetPillCounter():
          global pill_counter
          pill_counter = 0
          setNextPillTimer()
          updateDisplay()
          return str(SUCCESS_CODE
    
       def setPillIsDue():
          global pill_is_due
          pill_is_due = True
          updateDisplay()   
    
      def setNextPillTimer():
          global pill_is_due
          global timer
          if timer:
            timer.cancel()
          timer = Timer(PILL_TIMER_LIMIT, setPillIsDue, ())
          timer.start()
          pill_is_due = False
    
         def getPillCounter():
          return str(pill_counter)
    
      def getPillIsDueState():
          return str(pill_is_due)
    
  • Emergency Alarm:These are the functions used to set and reset an emergency alarm, which is shown to the user by turning a LED on or off.

      def toggleAlarm(alarmed):
          global alarm_status
          if alarmed:
            alarm_led.on()
            alarm_status = ON
      else:
          alarm_led.off()
          alarm_status = OFF
    
      def activateAlarm():
          toggleAlarm(ON)
          return str(SUCCESS_CODE)
    
      def resetAlarm():
          toggleAlarm(OFF)
          return str(SUCCESS_CODE)
    
      def getAlarmStatus():
          return alarm_status_list[alarm_status]
    
  • Input MonitoringThis section contains the function used to monitor the status of inputs, in this case the push button and the touch sensor, and execute the corresponding actions when their state changes.

      def checkButtonStatus():
      global pill_button_released
      global emergency_button_released
    
      if pill_button.value():
          if pill_button_released:
              administerPill()
              # avoid input until button is released
              pill_button_released = False
      else:
          # wait for new input
          pill_button_released = True
    
      if emergency_button.value():
          if emergency_button_released:
              toggleAlarm(ON)
              # avoid input until button is released
              emergency_button_released = False
      else:
          # wait for new input
          emergency_button_released = True
    
  • BluetoothThese functions and function dictionary are used to dynamically execute different actions depending on the function ID received by Bluetooth.

      def callFunction(fnc_id):
      func = btFunctionList.get(fnc_id, returnError)
      return func()
    
      def returnError():
          return "Error: Not valid code."
    
      btFunctionList = {'a': administerPill,
                        'b': activateAlarm,
                        'c': resetPillCounter,
                        'd': resetAlarm,
                        'e': getPillCounter,
                        'f': getAlarmStatus,
                        'g': getPillIsDueState}
    
  • Main Program Finally, this is the main function that is executed continuously to check for input events, after triggering the timer and LCD initialization tasks.

      def myProgram():
      global initialized
    
      if not initialized:
          displayInit(LCD_BACKGROUND_COLOR)
          updateDisplay()
          setNextPillTimer()
          initialized = True
    
      checkButtonStatus()
    

results matching ""

    No results matching ""