{ "cells": [ { "cell_type": "markdown", "id": "0199a11d", "metadata": {}, "source": [ "\n", "*This notebook contains material from [cbe61622](https://jckantor.github.io/cbe61622);\n", "content is available [on Github](https://github.com/jckantor/cbe61622.git).*\n" ] }, { "cell_type": "markdown", "id": "ddae3ca2", "metadata": {}, "source": [ "\n", "< [6.0 Device Coding](https://jckantor.github.io/cbe61622/06.00-Coding-for-Device-Control.html) | [Contents](toc.html) | [6.2 Coding for Device Control](https://jckantor.github.io/cbe61622/06.02-Coding-Paradigms.html) >
"
]
},
{
"cell_type": "markdown",
"id": "4ebbbd79-3481-4a55-bc3b-d49bf32fa305",
"metadata": {
"nbpages": {
"level": 1,
"link": "[6.1 Managing Multiple Devices with an Event Loop](https://jckantor.github.io/cbe61622/06.01-Simple_Event_Loop.html#6.1-Managing-Multiple-Devices-with-an-Event-Loop)",
"section": "6.1 Managing Multiple Devices with an Event Loop"
}
},
"source": [
"# 6.1 Managing Multiple Devices with an Event Loop"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "264d4b83-2add-4f06-86b4-429ec544f3b0",
"metadata": {
"nbpages": {
"level": 1,
"link": "[6.1 Managing Multiple Devices with an Event Loop](https://jckantor.github.io/cbe61622/06.01-Simple_Event_Loop.html#6.1-Managing-Multiple-Devices-with-an-Event-Loop)",
"section": "6.1 Managing Multiple Devices with an Event Loop"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"serial exception on close write failed: [Errno 6] Device not configured\n",
"Found serial ports: /dev/cu.usbmodem14301, /dev/cu.Bluetooth-Incoming-Port \n",
"\u001b[34mConnecting to --port=/dev/cu.usbmodem14301 --baud=115200 \u001b[0m\n",
"\u001b[34mReady.\n",
"\u001b[0m"
]
}
],
"source": [
"%serialconnect"
]
},
{
"cell_type": "markdown",
"id": "4a5b56a7-d6c0-4db5-8c70-828ed18c0b68",
"metadata": {
"nbpages": {
"level": 1,
"link": "[6.1 Managing Multiple Devices with an Event Loop](https://jckantor.github.io/cbe61622/06.01-Simple_Event_Loop.html#6.1-Managing-Multiple-Devices-with-an-Event-Loop)",
"section": "6.1 Managing Multiple Devices with an Event Loop"
}
},
"source": [
"The following example makes use of three Grove devices"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "55c737d3-69a8-491f-8a03-c7bfcc44d055",
"metadata": {
"nbpages": {
"level": 1,
"link": "[6.1 Managing Multiple Devices with an Event Loop](https://jckantor.github.io/cbe61622/06.01-Simple_Event_Loop.html#6.1-Managing-Multiple-Devices-with-an-Event-Loop)",
"section": "6.1 Managing Multiple Devices with an Event Loop"
}
},
"outputs": [],
"source": [
"# rotary angle sensor\n",
"\n",
"import machine\n",
"import time\n",
"from lcd1602 import LCD1602\n",
"\n",
"\n",
"class LCD16x2():\n",
" def __init__(self, i2c):\n",
" self.i2c = i2c\n",
" self.d = LCD1602(i2c, 2, 16)\n",
" self.d.clear()\n",
" self.lines = [\" \"*16, \" \"*16]\n",
" \n",
" def update(self, line1=None, line2=None):\n",
" self.update_line(0, line1)\n",
" self.update_line(1, line2)\n",
" \n",
" def update_line(self, j, line):\n",
" line = \"{:16s}\".format(line)\n",
" if line != self.lines[j]:\n",
" for i, char in enumerate(line):\n",
" self.d.setCursor(i, j)\n",
" self.d.write(ord(char))\n",
" self.lines[j] = line\n",
" \n",
" \n",
"class RotaryAngleSensor():\n",
" def __init__(self, adc):\n",
" self.adc = adc\n",
" \n",
" def value(self, n=10):\n",
" return (100/n/65535)*sum([self.adc.read_u16() for k in range(n)])\n",
" \n",
"\n",
"class Servo():\n",
" def __init__(self, pwm, freq=50, pulse_width_min=500, pulse_width_max=2500):\n",
" self.pwm = pwm\n",
" self.pwm.freq(freq)\n",
" self.pulse_width_min = pulse_width_min\n",
" self.pulse_width_max = pulse_width_max\n",
" self.pulse_width_us = 1500\n",
"\n",
" def set_position(self, pos):\n",
" pw = self.pulse_width_min + int((self.pulse_width_max - self.pulse_width_min)*pos/100)\n",
" self.pulse_width_us = max(self.pulse_width_min, min(self.pulse_width_max, pw))\n",
" self.pwm.duty_ns(1000*self.pulse_width_us)\n",
" \n",
"\n",
"sensor = RotaryAngleSensor(machine.ADC(0))\n",
"lcd = LCD16x2(machine.I2C(0))\n",
"servo = Servo(machine.PWM(machine.Pin(16, machine.Pin.OUT)))\n",
"\n",
"def main(timer):\n",
" global sensor, lcd, servo\n",
" pos = sensor.value()\n",
" servo.set_position(pos)\n",
" lcd.update(f\"ADC = {sensor.value():5.1f}%\", f\"pulse = {servo.pulse_width_us} us\")\n",
"\n",
"timer = machine.Timer(freq=100, mode=machine.Timer.PERIODIC, callback=main)\n"
]
},
{
"cell_type": "markdown",
"id": "22eef3b7-e425-413c-9db5-2fff5ef5a253",
"metadata": {
"nbpages": {
"level": 2,
"link": "[6.1.1 Activity](https://jckantor.github.io/cbe61622/06.01-Simple_Event_Loop.html#6.1.1-Activity)",
"section": "6.1.1 Activity"
}
},
"source": [
"## 6.1.1 Activity\n",
"\n",
"1. Use the oscilloscope and logic analyzer to verify ...\n",
" * The analog measurement on ADC(0)\n",
" * Pulse width modulation of the servo motor\n",
" * I2C communication with display\n",
" \n",
"2. Create a class to control a sensor or actuator (e.g., buzzer on Maker PI board, or PIR sensor).\n",
" * Read data sheet\n",
" * Determine what functionality is required.\n",
" * Write and test a class"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6e5a31d7-fea7-4250-bc2a-fc1ef173c980",
"metadata": {
"nbpages": {
"level": 2,
"link": "[6.1.1 Activity](https://jckantor.github.io/cbe61622/06.01-Simple_Event_Loop.html#6.1.1-Activity)",
"section": "6.1.1 Activity"
}
},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "2a169dff",
"metadata": {},
"source": [
"\n",
"< [6.0 Device Coding](https://jckantor.github.io/cbe61622/06.00-Coding-for-Device-Control.html) | [Contents](toc.html) | [6.2 Coding for Device Control](https://jckantor.github.io/cbe61622/06.02-Coding-Paradigms.html) >
"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "MicroPython - USB",
"language": "micropython",
"name": "micropython"
},
"language_info": {
"codemirror_mode": "python",
"file_extension": ".py",
"mimetype": "text/python",
"name": "micropython"
}
},
"nbformat": 4,
"nbformat_minor": 5
}