From b0519fc32f00a58c4b94551aafe902a182ccc03a Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Sat, 6 Apr 2019 13:23:50 -0700 Subject: [PATCH 01/18] Fixed to run on py3.7 (str.encode major issue) --- Arduino/arduino.py | 77 +++++++++++++++++++++++----------------------- tests/test_main.py | 12 ++++++-- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index d43c26e..84396f8 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -5,7 +5,9 @@ import serial import time from serial.tools import list_ports -if platform.system() == 'Windows': + +import sys +if sys.platform.startswith('win'): import _winreg as winreg else: import glob @@ -22,9 +24,9 @@ def enumerate_serial_ports(): path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM' try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path) - except WindowsError: + except OSError: # TODO raise Exception - + for i in itertools.count(): try: val = winreg.EnumValue(key, i) @@ -85,7 +87,7 @@ def find_port(baud, timeout): def get_version(sr): cmd_str = build_cmd_str("version") try: - sr.write(cmd_str) + sr.write(str.encode(cmd_str)) sr.flush() except Exception: return None @@ -130,7 +132,7 @@ def digitalWrite(self, pin, val): pin_ = pin cmd_str = build_cmd_str("dw", (pin_,)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -150,7 +152,7 @@ def analogWrite(self, pin, val): val = 0 cmd_str = build_cmd_str("aw", (pin, val)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -166,7 +168,7 @@ def analogRead(self, pin): """ cmd_str = build_cmd_str("ar", (pin,)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -189,7 +191,7 @@ def pinMode(self, pin, val): pin_ = pin cmd_str = build_cmd_str("pm", (pin_,)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -209,7 +211,7 @@ def pulseIn(self, pin, val): pin_ = pin cmd_str = build_cmd_str("pi", (pin_,)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -256,7 +258,7 @@ def pulseIn_set(self, pin, val, numTrials=5): durations = [] for s in range(numTrials): try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -290,7 +292,7 @@ def digitalRead(self, pin): """ cmd_str = build_cmd_str("dr", (pin,)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -335,18 +337,18 @@ def Melody(self, pin, melody, durations): cmd_args = [length, pin] if length == len(durations): cmd_args.extend([NOTES.get(melody[note]) - for note in range(length)]) + for note in range(length)]) cmd_args.extend([durations[duration] - for duration in range(len(durations))]) + for duration in range(len(durations))]) cmd_str = build_cmd_str("to", cmd_args) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass cmd_str = build_cmd_str("nto", [pin]) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -369,7 +371,7 @@ def capacitivePin(self, pin): the Arduino/Shrimp and any hardware attached to the pin. ''' cmd_str = build_cmd_str("cap", (pin,)) - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) rd = self.sr.readline().replace("\r\n", "") if rd.isdigit(): return int(rd) @@ -386,7 +388,7 @@ def shiftOut(self, dataPin, clockPin, pinOrder, value): """ cmd_str = build_cmd_str("so", (dataPin, clockPin, pinOrder, value)) - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() def shiftIn(self, dataPin, clockPin, pinOrder): @@ -401,7 +403,7 @@ def shiftIn(self, dataPin, clockPin, pinOrder): (int) an integer from 0 to 255 """ cmd_str = build_cmd_str("si", (dataPin, clockPin, pinOrder)) - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() rd = self.sr.readline().replace("\r\n", "") if rd.isdigit(): @@ -441,7 +443,7 @@ def attach(self, pin, min=544, max=2400): cmd_str = build_cmd_str("sva", (pin, min, max)) while True: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() rd = self.sr.readline().replace("\r\n", "") @@ -457,7 +459,7 @@ def detach(self, pin): position = self.servo_pos[pin] cmd_str = build_cmd_str("svd", (position,)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -467,14 +469,14 @@ def write(self, pin, angle): position = self.servo_pos[pin] cmd_str = build_cmd_str("svw", (position, angle)) - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() def writeMicroseconds(self, pin, uS): position = self.servo_pos[pin] cmd_str = build_cmd_str("svwm", (position, uS)) - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() def read(self, pin): @@ -483,7 +485,7 @@ def read(self, pin): position = self.servo_pos[pin] cmd_str = build_cmd_str("svr", (position,)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -513,7 +515,7 @@ def begin(self, p1, p2, baud): """ cmd_str = build_cmd_str("ss", (p1, p2, baud)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -533,7 +535,7 @@ def write(self, data): if self.connected: cmd_str = build_cmd_str("sw", (data,)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass @@ -550,7 +552,7 @@ def read(self): """ if self.connected: cmd_str = build_cmd_str("sr") - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() response = self.sr.readline().replace("\r\n", "") if response: @@ -561,7 +563,7 @@ def read(self): class EEPROM(object): """ - Class for reading and writing to EEPROM. + Class for reading and writing to EEPROM. """ def __init__(self, board): @@ -573,45 +575,44 @@ def size(self): Returns size of EEPROM memory. """ cmd_str = build_cmd_str("sz") - + try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() response = self.sr.readline().replace("\r\n", "") return int(response) except: return 0 - + def write(self, address, value=0): """ Write a byte to the EEPROM. - + :address: the location to write to, starting from 0 (int) :value: the value to write, from 0 to 255 (byte) """ - + if value > 255: value = 255 elif value < 0: value = 0 cmd_str = build_cmd_str("eewr", (address, value)) try: - self.sr.write(cmd_str) + self.sr.write(str.encode(cmd_str)) self.sr.flush() except: pass - + def read(self, adrress): """ Reads a byte from the EEPROM. - + :address: the location to write to, starting from 0 (int) """ cmd_str = build_cmd_str("eer", (adrress,)) try: - self.sr.write(cmd_str) - self.sr.flush() + self.sr.write(str.encode(cmd_str)) + self.sr.flush() response = self.sr.readline().replace("\r\n", "") if response: return int(response) except: return 0 - diff --git a/tests/test_main.py b/tests/test_main.py index 0ec221f..0a12a66 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -14,12 +14,18 @@ logging.basicConfig(level=logging.DEBUG) +# Bind raw_input to input in python 2.7 +try: + input = raw_input +except NameError: + pass + class TestBasics(unittest.TestCase): def test_find(self): """ Tests auto-connection/board detection. """ - raw_input( + input( 'Plug in Arduino board w/LED at pin 13, reset, then press enter') from Arduino import Arduino board = None @@ -34,11 +40,11 @@ def test_open(self): """ Tests connecting to an explicit port. """ port = None while not port: - port = raw_input( + port = input( 'Plug in Arduino board w/LED at pin 13, reset.\n'\ 'Enter the port where the Arduino is connected, then press enter:') if not port: - print 'You must enter a port.' + print('You must enter a port.') from Arduino import Arduino board = None try: From 0b299f17a3ab5ce24e3b7dc4f0245b3f12fc8a63 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Mon, 8 Apr 2019 13:04:53 -0700 Subject: [PATCH 02/18] Updated import of winreg --- Arduino/arduino.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index 84396f8..aa84d37 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -8,7 +8,7 @@ import sys if sys.platform.startswith('win'): - import _winreg as winreg + import winreg else: import glob @@ -24,7 +24,7 @@ def enumerate_serial_ports(): path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM' try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path) - except OSError: # TODO + except OSError: raise Exception for i in itertools.count(): From e2a464412b7f0b37e62406abaf3715e55fdf6d92 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Tue, 9 Apr 2019 14:04:19 -0700 Subject: [PATCH 03/18] Converted byte litterals to strings for comparion in unit tests --- tests/test_arduino.py | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/test_arduino.py b/tests/test_arduino.py index 51c138d..650b4c0 100644 --- a/tests/test_arduino.py +++ b/tests/test_arduino.py @@ -85,21 +85,21 @@ def test_version(self): from Arduino.arduino import build_cmd_str expected_version = "version" self.mock_serial.push_line(expected_version) - self.assertEquals(self.board.version(), expected_version) - self.assertEquals(self.mock_serial.output[0], build_cmd_str('version')) + self.assertEqual(self.board.version(), expected_version) + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('version')) def test_pinMode_input(self): from Arduino.arduino import build_cmd_str pin = 9 self.board.pinMode(pin, INPUT) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('pm', (-pin,))) def test_pinMode_output(self): from Arduino.arduino import build_cmd_str pin = 9 self.board.pinMode(pin, OUTPUT) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('pm', (pin,))) def test_pulseIn_low(self): @@ -107,8 +107,8 @@ def test_pulseIn_low(self): expected_duration = 230 self.mock_serial.push_line(expected_duration) pin = 9 - self.assertEquals(self.board.pulseIn(pin, LOW), expected_duration) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.board.pulseIn(pin, LOW), expected_duration) + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('pi', (-pin,))) def test_pulseIn_high(self): @@ -116,27 +116,27 @@ def test_pulseIn_high(self): expected_duration = 230 pin = 9 self.mock_serial.push_line(expected_duration) - self.assertEquals(self.board.pulseIn(pin, HIGH), expected_duration) - self.assertEquals(self.mock_serial.output[0], build_cmd_str('pi', (pin,))) + self.assertEqual(self.board.pulseIn(pin, HIGH), expected_duration) + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('pi', (pin,))) def test_digitalRead(self): from Arduino.arduino import build_cmd_str pin = 9 self.mock_serial.push_line(READ_LOW) - self.assertEquals(self.board.digitalRead(pin), READ_LOW) - self.assertEquals(self.mock_serial.output[0], build_cmd_str('dr', (pin,))) + self.assertEqual(self.board.digitalRead(pin), READ_LOW) + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('dr', (pin,))) def test_digitalWrite_low(self): from Arduino.arduino import build_cmd_str pin = 9 self.board.digitalWrite(pin, LOW) - self.assertEquals(self.mock_serial.output[0], build_cmd_str('dw', (-pin,))) + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('dw', (-pin,))) def test_digitalWrite_high(self): from Arduino.arduino import build_cmd_str pin = 9 self.board.digitalWrite(pin, HIGH) - self.assertEquals(self.mock_serial.output[0], build_cmd_str('dw', (pin,))) + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('dw', (pin,))) def test_melody(self): from Arduino.arduino import build_cmd_str @@ -145,9 +145,9 @@ def test_melody(self): duration = 4 C4_NOTE = 262 self.board.Melody(pin, notes, [duration]) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('to', (len(notes), pin, C4_NOTE, duration))) - self.assertEquals(self.mock_serial.output[1], + self.assertEqual(self.mock_serial.output[1].decode('UTF-8'), build_cmd_str('nto', (pin,))) def test_shiftIn(self): @@ -157,9 +157,9 @@ def test_shiftIn(self): pinOrder = MSBFIRST expected = 0xff self.mock_serial.push_line(expected) - self.assertEquals(self.board.shiftIn(dataPin, clockPin, pinOrder), + self.assertEqual(self.board.shiftIn(dataPin, clockPin, pinOrder), expected) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('si', (dataPin, clockPin, pinOrder,))) def test_shiftOut(self): @@ -169,7 +169,7 @@ def test_shiftOut(self): pinOrder = MSBFIRST value = 0xff self.board.shiftOut(dataPin, clockPin, pinOrder, value) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('so', (dataPin, clockPin, pinOrder, value))) def test_analogRead(self): @@ -177,8 +177,8 @@ def test_analogRead(self): pin = 9 expected = 1023 self.mock_serial.push_line(expected) - self.assertEquals(self.board.analogRead(pin), expected) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.board.analogRead(pin), expected) + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('ar', (pin,))) def test_analogWrite(self): @@ -186,7 +186,7 @@ def test_analogWrite(self): pin = 9 value = 255 self.board.analogWrite(pin, value) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('aw', (pin, value))) @@ -200,7 +200,7 @@ def test_attach(self): servo_min = 544 servo_max = 2400 self.board.Servos.attach(pin, min=servo_min, max=servo_max) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('sva', (pin, servo_min, servo_max))) def test_detach(self): @@ -212,7 +212,7 @@ def test_detach(self): self.board.Servos.attach(pin) self.mock_serial.reset_mock() self.board.Servos.detach(pin) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str('svd', (position,))) def test_write(self): @@ -225,7 +225,7 @@ def test_write(self): self.board.Servos.attach(pin) self.mock_serial.reset_mock() self.board.Servos.write(pin, angle) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str("svw", (position, angle))) def test_writeMicroseconds(self): @@ -238,7 +238,7 @@ def test_writeMicroseconds(self): self.board.Servos.attach(pin) self.mock_serial.reset_mock() self.board.Servos.writeMicroseconds(pin, microseconds) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str("svwm", (position, microseconds))) def test_read(self): @@ -251,8 +251,8 @@ def test_read(self): self.board.Servos.attach(pin) self.mock_serial.reset_mock() self.mock_serial.push_line(angle) - self.assertEquals(self.board.Servos.read(pin), angle) - self.assertEquals(self.mock_serial.output[0], + self.assertEqual(self.board.Servos.read(pin), angle) + self.assertEqual(self.mock_serial.output[0].decode('UTF-8'), build_cmd_str("svr", (position,))) From b0c7be55c70e3bab0303979a62218adfac6cea5d Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Tue, 9 Apr 2019 14:44:12 -0700 Subject: [PATCH 04/18] Minor changes for dist --- Arduino/__init__.py | 1 + README.md | 27 ++++++++++++++------------- setup.py | 30 ++++++++++++++++++------------ 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/Arduino/__init__.py b/Arduino/__init__.py index 34ac945..ffc5252 100644 --- a/Arduino/__init__.py +++ b/Arduino/__init__.py @@ -1 +1,2 @@ +name="arduino-python3" from .arduino import Arduino, Shrimp diff --git a/README.md b/README.md index 07095ab..216aab1 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ -# Python Arduino Command API +# Python3 Arduino Command API -The Python Arduino Command API is a light-weight Python library for +This API is forked from the original [Python Arduino Command API](https://github.com/thearn/Python-Arduino-Command-API) to add support for Python 3. + +The Python Arduino Command API is a lightweight Python library for communicating with [Arduino microcontroller boards](http://www.arduino.cc/) from a connected computer using -standard serial IO, either over a physical wire +standard serial IO, either over a physical wire or wirelessly. It is written using a custom protocol, similar to [Firmata](http://firmata.org/wiki/Main_Page). -This allows a user to quickly protoype programs for Arduino using Python code, or to +This allows a user to quickly prototype programs for Arduino using Python code, or to simply read/control/troubleshoot/experiment -with harware connected to an Arduino board without ever having to recompile and reload sketches to the board itself. +with hardware connected to an Arduino board without ever having to recompile and reload sketches to the board itself. Method names within the Python Arduino Command API are designed to be as close as possible to their Arduino programming language counterparts @@ -34,12 +36,12 @@ while True: ``` ## Requirements: -- [Python](http://python.org/) 2.3 or higher (Python 3.x not yet tested, but would probably work) +- [Python](http://python.org/) 3.7 tested on Windows and macOS. - [pyserial](http://pyserial.sourceforge.net/) 2.6 or higher - Any [Arduino compatible microcontroller](https://www.sparkfun.com/categories/242) with at least 14KB of flash memory ## Installation: -Either run `pip install arduino-python` from a command line, or run `python setup.py +Either run `pip install arduino-python3` from a command line, or run `python setup.py build install` from the source directory to install this library. ## Setup: @@ -47,7 +49,7 @@ build install` from the source directory to install this library. `setup()` function (line 348) in `prototype.ino`. Change it there if necessary. 2. Load the `prototype.ino` sketch onto your Arduino board, using the Arduino IDE. 3. Set up some kind of serial I/O communication between the Arduino board and your computer (via physical USB cable, -bluetooth, xbee, etc + associated drivers) +Bluetooth, xbee, etc. + associated drivers) 4. Add `from Arduino import Arduino` into your python script to communicate with your Arduino For a collection of examples, see `examples.py`. This file contains methods which replicate @@ -161,9 +163,9 @@ board.Servos.detach(9) #free pin 9 - `Arduino.SoftwareSerial.begin(ss_rxPin, ss_txPin, ss_device_baud)` initialize software serial device on specified pins. -Only one sofware serial device can be used at a time. Existing software serial instance will -be be overwritten by calling this method, both in Python and on the arduino board. -- `Arduino.SoftwareSerial.write(data)` send data using the arduino 'write' function to the existing software +Only one software serial device can be used at a time. Existing software serial instance will +be overwritten by calling this method, both in Python and on the Arduino board. +- `Arduino.SoftwareSerial.write(data)` send data using the Arduino 'write' function to the existing software serial connection. - `Arduino.SoftwareSerial.read()` returns one byte from the existing software serial connection @@ -185,7 +187,7 @@ response_char = board.SoftwareSerial.read() #read response character location = 42 value = 10 # 0-255(byte) -board.EEPROM.write(location, 10) +board.EEPROM.write(location, 10) print(board.EEPROM.read(location)) print('EEPROM size {size}'.format(size=board.EEPROM.size())) ``` @@ -201,4 +203,3 @@ print('EEPROM size {size}'.format(size=board.EEPROM.size())) - Include a wizard which generates 'prototype.ino' with selected serial baud rate and Arduino function support (to help reduce memory requirements). - Multi-serial support for Arduino mega (`Serial1.read()`, etc) - diff --git a/setup.py b/setup.py index f82f35d..88fbb66 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,19 @@ -from setuptools import setup +import setuptools -setup(name='arduino-python', - version='0.2', - install_requires=['pyserial'], - description="A light-weight Python library that provides a serial \ - bridge for communicating with Arduino microcontroller boards.", - author='Tristan Hearn', - author_email='tristanhearn@gmail.com', - url='https://github.com/thearn/Python-Arduino-Command-API', - license='MIT', - packages=['Arduino'], - ) +with open("README.md", "r") as fh: + long_description = fh.read() + +setuptools.setup( + name="arduino-python3", + version="0.1", + install_requires=['pyserial'], + author="Morten Kals", + author_email="morten@kals.no", + description="A light-weight Python library that provides a serial \ + bridge for communicating with Arduino microcontroller boards. Extended to work with Python 3", + long_description=long_description, + long_description_content_type="text/markdown", + url='https://github.com/mkals/Python-Arduino-Command-API', + packages=['Arduino'], + license='MIT', +) From f4996c69d90cc6dc787833bdebc83cf3aa9b636c Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Tue, 9 Apr 2019 16:45:58 -0700 Subject: [PATCH 05/18] Fixed decoding bug --- Arduino/arduino.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index aa84d37..499252f 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -172,7 +172,7 @@ def analogRead(self, pin): self.sr.flush() except: pass - rd = self.sr.readline().replace("\r\n", "") + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") try: return int(rd) except: @@ -215,7 +215,7 @@ def pulseIn(self, pin, val): self.sr.flush() except: pass - rd = self.sr.readline().replace("\r\n", "") + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") try: return float(rd) except: @@ -262,7 +262,7 @@ def pulseIn_set(self, pin, val, numTrials=5): self.sr.flush() except: pass - rd = self.sr.readline().replace("\r\n", "") + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") if rd.isdigit(): if (int(rd) > 1): durations.append(int(rd)) @@ -296,7 +296,7 @@ def digitalRead(self, pin): self.sr.flush() except: pass - rd = self.sr.readline().replace("\r\n", "") + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") try: return int(rd) except: @@ -372,7 +372,7 @@ def capacitivePin(self, pin): ''' cmd_str = build_cmd_str("cap", (pin,)) self.sr.write(str.encode(cmd_str)) - rd = self.sr.readline().replace("\r\n", "") + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") if rd.isdigit(): return int(rd) @@ -405,7 +405,7 @@ def shiftIn(self, dataPin, clockPin, pinOrder): cmd_str = build_cmd_str("si", (dataPin, clockPin, pinOrder)) self.sr.write(str.encode(cmd_str)) self.sr.flush() - rd = self.sr.readline().replace("\r\n", "") + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") if rd.isdigit(): return int(rd) @@ -446,7 +446,7 @@ def attach(self, pin, min=544, max=2400): self.sr.write(str.encode(cmd_str)) self.sr.flush() - rd = self.sr.readline().replace("\r\n", "") + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") if rd: break else: @@ -489,7 +489,7 @@ def read(self, pin): self.sr.flush() except: pass - rd = self.sr.readline().replace("\r\n", "") + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") try: angle = int(rd) return angle From fee75cfbcecb0fe13463e86adb9eb5b69936bb25 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Tue, 9 Apr 2019 16:59:38 -0700 Subject: [PATCH 06/18] updated version for next upload --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 88fbb66..52fa795 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="arduino-python3", - version="0.1", + version="0.2", install_requires=['pyserial'], author="Morten Kals", author_email="morten@kals.no", From 2d49f8858b0770a6a67b290536a480c13e679767 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Sat, 20 Apr 2019 22:21:12 -0700 Subject: [PATCH 07/18] Updates to fix connection issue on startup and added support for DHT sensors --- Arduino/arduino.py | 59 +++++++++++++++++++++++++++++-- sketches/prototype/prototype.ino | 60 ++++++++++++++++++++++++++++---- 2 files changed, 110 insertions(+), 9 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index 499252f..30bd6bf 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -108,6 +108,7 @@ def __init__(self, baud=9600, port=None, timeout=2, sr=None): raise ValueError("Could not find port.") else: sr = serial.Serial(port, baud, timeout=timeout) + sr.readline() sr.flush() self.sr = sr self.SoftwareSerial = SoftwareSerial(self) @@ -126,7 +127,7 @@ def digitalWrite(self, pin, val): pin : digital pin number val : either "HIGH" or "LOW" """ - if val == "LOW": + if val.upper() == "LOW": pin_ = -pin else: pin_ = pin @@ -205,7 +206,7 @@ def pulseIn(self, pin, val): returns: duration : pulse length measurement """ - if val == "LOW": + if val.upper() == "LOW": pin_ = -pin else: pin_ = pin @@ -250,7 +251,7 @@ def pulseIn_set(self, pin, val, numTrials=5): pinMode(pin, INPUT); long duration = pulseIn(pin, HIGH); """ - if val == "LOW": + if val.upper() == "LOW": pin_ = -pin else: pin_ = pin @@ -410,6 +411,57 @@ def shiftIn(self, dataPin, clockPin, pinOrder): return int(rd) + def dht(self, pin, module = 0): + """ + Read data from dht temperature and humidity sensors based on the + Adafruit DHT sensor library. + https://github.com/adafruit/DHT-sensor-library + + Guide for using library: + https://learn.adafruit.com/dht/using-a-dhtxx-sensor + + There are five sensors that work with this library: + - DHT 11: blue cage, less accurate + - DHT 12: + - DHT 21: + - DHT 22: white cage + - AM2301: + Input: + pin (int): pin for data + module (int): 0 = DHT 11 (default), + 1 = DHT 12, + 2 = DHT 21, + 3 = DHT 22, + 4 = AM2301 + Output: + [float, float, float] in the format: + [ humidity in %, + temperature in celcius, + heat index in celcius ] + """ + try: + if not (0 <= module <= 4): + print("unknown module, must be in range 0 to 4. Using 0 (DHT 11).") # raise exception + except: + module = 0 + print("module must be spesified using an integer. Using 0 (DHT 11).") + + cmd_str = build_cmd_str("dht", (pin, module,)) + try: + self.sr.write(str.encode(cmd_str)) + self.sr.flush() + except: + pass + rd = self.sr.readline().decode("utf-8").replace("\r\n", "") + try: + strings = rd.split("&") + return [float(s) for s in strings] + except: + return None + + + + class Shrimp(Arduino): def __init__(self): @@ -497,6 +549,7 @@ def read(self, pin): return None + class SoftwareSerial(object): """ diff --git a/sketches/prototype/prototype.ino b/sketches/prototype/prototype.ino index cee57ab..f364e6d 100644 --- a/sketches/prototype/prototype.ino +++ b/sketches/prototype/prototype.ino @@ -2,6 +2,7 @@ #include #include #include +#include SoftwareSerial *sserial = NULL; Servo servos[8]; @@ -316,6 +317,49 @@ void EEPROMHandler(int mode, String data) { } } +int dhtSensorPin = -1; +DHT dhtSensor(dhtSensorPin, DHT11); + +void dht(String data) { + + String sdata[2]; + split(sdata, 2, data, '%'); + int dataPin = sdata[0].toInt(); + int sensorNumber = sdata[1].toInt(); + + int sensorType = DHT11; // assume DHT11 as default + if (sensorNumber == 1) { + sensorType = DHT12; + } else if (sensorNumber == 2) { + sensorType = DHT21; + } else if (sensorNumber == 2) { + sensorType = DHT22; + } else if (sensorNumber == 2) { + sensorType = AM2301; + } + + // do not initialize new sensor if we are reading repeatedly from same sensor + if (dataPin != dhtSensorPin) { + dhtSensorPin = dataPin; + dhtSensor = DHT(dataPin, sensorType); + dhtSensor.begin(); + } + + // Reading temperature or humidity takes about 250 milliseconds! + // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) + float h = dhtSensor.readHumidity(); + // Read temperature as Celsius (the default) + float t = dhtSensor.readTemperature(); + + if (isnan(h) || isnan(t)) { + Serial.println("0&0&0"); + return; + } + + float hic = dhtSensor.computeHeatIndex(t, h, false); + Serial.println(String(h) + "&" + String(t) + "&" + String(hic)); +} + void SerialParser(void) { char readChar[64]; Serial.readBytesUntil(33,readChar,64); @@ -399,16 +443,20 @@ void SerialParser(void) { } else if (cmd == "sz") { sizeEEPROM(); - } + } + else if (cmd == "dht") { + dht(data); + } } void setup() { - Serial.begin(9600); + Serial.begin(115200); while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } + ; // wait for serial port to connect. Needed for Leonardo only + } + Serial.println("connected"); } void loop() { - SerialParser(); - } + SerialParser(); +} From fbfc079cff34d38506d671212f5a13587cb65051 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Sat, 20 Apr 2019 22:46:38 -0700 Subject: [PATCH 08/18] Updated baud and added DHT section to readme --- Arduino/arduino.py | 2 +- README.md | 45 ++++++++++++++++++++++++++++++++++++++----- examples.py | 2 +- setup.py | 2 +- tests/test_arduino.py | 2 +- tests/test_main.py | 4 ++-- 6 files changed, 46 insertions(+), 11 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index 30bd6bf..c4828b2 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -96,7 +96,7 @@ def get_version(sr): class Arduino(object): - def __init__(self, baud=9600, port=None, timeout=2, sr=None): + def __init__(self, baud=115200, port=None, timeout=2, sr=None): """ Initializes serial communication with Arduino if no connection is given. Attempts to self-select COM port, if not specified. diff --git a/README.md b/README.md index 216aab1..ac18634 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ as possible to their Arduino programming language counterparts from Arduino import Arduino import time -board = Arduino('9600') #plugged in via USB, serial com at rate 9600 +board = Arduino('115200') #plugged in via USB, serial com at rate 115200 board.pinMode(13, "OUTPUT") while True: @@ -76,7 +76,7 @@ $ python tests/test_arduino.py Arduino. ```python -board = Arduino("9600") #Example +board = Arduino("115200") #Example ``` The device name / COM port of the connected Arduino will be auto-detected. @@ -84,17 +84,17 @@ If there are more than one Arduino boards connected, the desired COM port can be also be passed as an optional argument: ```python -board = Arduino("9600", port="COM3") #Windows example +board = Arduino("115200", port="COM3") #Windows example ``` ```python -board = Arduino("9600", port="/dev/tty.usbmodemfa141") #OSX example +board = Arduino("115200", port="/dev/tty.usbmodemfa141") #OSX example ``` A time-out for reading from the Arduino can also be specified as an optional argument: ```python -board = Arduino("9600", timeout=2) #Serial reading functions will +board = Arduino("115200", timeout=2) #Serial reading functions will #wait for no more than 2 seconds ``` @@ -192,6 +192,41 @@ print(board.EEPROM.read(location)) print('EEPROM size {size}'.format(size=board.EEPROM.size())) ``` +**DHT** +Read data from DHT temperature and humidity sensors based on the +Adafruit [DHT sensor library](https://github.com/adafruit/DHT-sensor-library). + +Pass as arguments the pin the sensor is connected to (as an integer) and the sensor type you are using as an integer (see list below). + +There are five sensors that work with this library: +- 0 = DHT 11 (blue cage, less accurate) +- 1 = DHT 12 +- 2 = DHT 21 +- 3 = DHT 22 (white cage) +- 4 = AM2301 + +The function returns an array of three elements: +1. humidity (in %) +2. temperature (in celcius) +3. heat index (in celcius) + +If there is an error with the reading (eg. the selected sensor is wrong) all values will return as zero. + +```python +#DHT sensor example +pin = 7 +sensorType = 0 + +data = board.dht(pin, sensorType) +[humidity, temperature, heatIndex] = data + +reply = "Humidity = " + str(humidity) + " % \t" +reply += "Temperature = " + str(temperature) + " ˙C \t" +reply += "Heat Index = " + str(heatIndex) + " ˙C" + +print(reply) +``` + **Misc** - `Arduino.close()` closes serial connection to the Arduino. diff --git a/examples.py b/examples.py index 21c6e0f..2da6906 100644 --- a/examples.py +++ b/examples.py @@ -73,4 +73,4 @@ def LCD(tx, baud, ssbaud, message, port=""): board.SoftwareSerial.write(" test ") if __name__ == "__main__": - Blink(13, '9600') + Blink(13, '115200') diff --git a/setup.py b/setup.py index 52fa795..5ed9934 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="arduino-python3", - version="0.2", + version="0.3", install_requires=['pyserial'], author="Morten Kals", author_email="morten@kals.no", diff --git a/tests/test_arduino.py b/tests/test_arduino.py index 650b4c0..21e76e8 100644 --- a/tests/test_arduino.py +++ b/tests/test_arduino.py @@ -58,7 +58,7 @@ class ArduinoTestCase(unittest.TestCase): def setUp(self): from Arduino.arduino import Arduino - self.mock_serial = MockSerial(9600, '/dev/ttyACM0') + self.mock_serial = MockSerial(115200, '/dev/ttyACM0') self.board = Arduino(sr=self.mock_serial) diff --git a/tests/test_main.py b/tests/test_main.py index 0a12a66..9f414b4 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -31,7 +31,7 @@ def test_find(self): board = None try: # This will trigger automatic port resolution. - board = Arduino(9600) + board = Arduino(115200) finally: if board: board.close() @@ -48,7 +48,7 @@ def test_open(self): from Arduino import Arduino board = None try: - board = Arduino(9600, port=port) + board = Arduino(115200, port=port) finally: if board: board.close() From a5c07b54790695aaf7675e71ce38bee3cc468aaf Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Sun, 21 Apr 2019 13:22:59 -0700 Subject: [PATCH 09/18] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ac18634..ec1dc8e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Python3 Arduino Command API +# Arduino-Python3 Command API This API is forked from the original [Python Arduino Command API](https://github.com/thearn/Python-Arduino-Command-API) to add support for Python 3. From c1f426507602aa82aedc02a723789c10174304c3 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Sun, 21 Apr 2019 16:01:26 -0700 Subject: [PATCH 10/18] Fixed auto-connect, decode bug and added firmware version check --- Arduino/arduino.py | 46 ++++++++++++++++++++++---------- Arduino/temp.py | 25 +++++++++++++++++ README.md | 15 ++++++----- setup.py | 4 +-- sketches/prototype/prototype.ino | 9 ++++--- 5 files changed, 73 insertions(+), 26 deletions(-) create mode 100644 Arduino/temp.py diff --git a/Arduino/arduino.py b/Arduino/arduino.py index c4828b2..f7f7d58 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -12,6 +12,7 @@ else: import glob +libraryVersion = 'V0.4' log = logging.getLogger(__name__) @@ -62,6 +63,7 @@ def find_port(baud, timeout): ports = enumerate_serial_ports() elif platform.system() == 'Darwin': ports = [i[0] for i in list_ports.comports()] + ports = ports[::-1] else: ports = glob.glob("/dev/ttyUSB*") + glob.glob("/dev/ttyACM*") for p in ports: @@ -71,19 +73,27 @@ def find_port(baud, timeout): except (serial.serialutil.SerialException, OSError) as e: log.debug(str(e)) continue - time.sleep(2) + + sr.readline() # wait for board to start up again + version = get_version(sr) - if version != 'version': - log.debug('Bad version {0}. This is not a Shrimp/Arduino!'.format( - version)) - sr.close() - continue + + if version != libraryVersion: + if version[0] == 'V' or version == "version": + print("You need to update the version of the Arduino-Python3 ", + "library running on your Arduino. ", + "Flash the prototype sketch again.") + return sr + else: + log.debug('Bad version {0}. This is not a Shrimp/Arduino!'.format( + version)) + sr.close() + continue log.info('Using port {0}.'.format(p)) if sr: return sr return None - def get_version(sr): cmd_str = build_cmd_str("version") try: @@ -91,11 +101,12 @@ def get_version(sr): sr.flush() except Exception: return None - return sr.readline().replace("\r\n", "") + return sr.readline().decode("utf-8").replace("\r\n", "") class Arduino(object): + def __init__(self, baud=115200, port=None, timeout=2, sr=None): """ Initializes serial communication with Arduino if no connection is @@ -108,7 +119,14 @@ def __init__(self, baud=115200, port=None, timeout=2, sr=None): raise ValueError("Could not find port.") else: sr = serial.Serial(port, baud, timeout=timeout) - sr.readline() + sr.readline() # wait til board has rebooted and is connected + + # check version + if get_version(sr) != libraryVersion: + print("You need to update the version of the Arduino-Python3 ", + "library running on your Arduino. ", + "Flash the prototype sketch again.") + sr.flush() self.sr = sr self.SoftwareSerial = SoftwareSerial(self) @@ -572,7 +590,7 @@ def begin(self, p1, p2, baud): self.sr.flush() except: pass - response = self.sr.readline().replace("\r\n", "") + response = self.sr.readline().decode("utf-8").replace("\r\n", "") if response == "ss OK": self.connected = True return True @@ -592,7 +610,7 @@ def write(self, data): self.sr.flush() except: pass - response = self.sr.readline().replace("\r\n", "") + response = self.sr.readline().decode("utf-8").replace("\r\n", "") if response == "ss OK": return True else: @@ -607,7 +625,7 @@ def read(self): cmd_str = build_cmd_str("sr") self.sr.write(str.encode(cmd_str)) self.sr.flush() - response = self.sr.readline().replace("\r\n", "") + response = self.sr.readline().decode("utf-8").replace("\r\n", "") if response: return response else: @@ -632,7 +650,7 @@ def size(self): try: self.sr.write(str.encode(cmd_str)) self.sr.flush() - response = self.sr.readline().replace("\r\n", "") + response = self.sr.readline().decode("utf-8").replace("\r\n", "") return int(response) except: return 0 @@ -664,7 +682,7 @@ def read(self, adrress): try: self.sr.write(str.encode(cmd_str)) self.sr.flush() - response = self.sr.readline().replace("\r\n", "") + response = self.sr.readline().decode("utf-8").replace("\r\n", "") if response: return int(response) except: diff --git a/Arduino/temp.py b/Arduino/temp.py new file mode 100644 index 0000000..ae20e1f --- /dev/null +++ b/Arduino/temp.py @@ -0,0 +1,25 @@ + +from arduino import Arduino + +board = Arduino() + +#from Arduino import Arduino +#import time +# +#PORT_NAME = '/dev/tty.usbserial-1410' # MUST BE UPDATED TO USE THE CORRECT PORT +#PIN_SENSE = 12 # pin where ultrasic sensor is connected +# +## connect to Arduino +#board = Arduino(port=PORT_NAME) +#print('Connected') +# +#try: +# while True: +# # make distance measurement +# pulseTime = board.pulseIn_set(PIN_SENSE, 'HIGH') +# print(pulseTime) +# +# time.sleep(1) # delay to keep UART bus for getting overloaded +# +#except KeyboardInterrupt: +# board.close() # close serial connection \ No newline at end of file diff --git a/README.md b/README.md index ec1dc8e..15255eb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This API is forked from the original [Python Arduino Command API](https://github.com/thearn/Python-Arduino-Command-API) to add support for Python 3. -The Python Arduino Command API is a lightweight Python library for +The Arduino-Python3 Command API is a lightweight Python library for communicating with [Arduino microcontroller boards](http://www.arduino.cc/) from a connected computer using standard serial IO, either over a physical wire or wirelessly. It is written using a custom protocol, similar to [Firmata](http://firmata.org/wiki/Main_Page). @@ -11,7 +11,7 @@ This allows a user to quickly prototype programs for Arduino using Python code, simply read/control/troubleshoot/experiment with hardware connected to an Arduino board without ever having to recompile and reload sketches to the board itself. -Method names within the Python Arduino Command API are designed to be as close +Method names within the Arduino-Python3 Command API are designed to be as close as possible to their Arduino programming language counterparts ## Simple usage example (LED blink) @@ -25,7 +25,7 @@ as possible to their Arduino programming language counterparts from Arduino import Arduino import time -board = Arduino('115200') #plugged in via USB, serial com at rate 115200 +board = Arduino() # plugged in via USB, serial com at rate 115200 board.pinMode(13, "OUTPUT") while True: @@ -193,6 +193,9 @@ print('EEPROM size {size}'.format(size=board.EEPROM.size())) ``` **DHT** + +- `Arduino.dht(pin, module)` reads sensor values from the DHT sensor connected at the specified pin. + Read data from DHT temperature and humidity sensors based on the Adafruit [DHT sensor library](https://github.com/adafruit/DHT-sensor-library). @@ -207,10 +210,10 @@ There are five sensors that work with this library: The function returns an array of three elements: 1. humidity (in %) -2. temperature (in celcius) -3. heat index (in celcius) +2. temperature (in Celsius) +3. heat index (in Celsius) -If there is an error with the reading (eg. the selected sensor is wrong) all values will return as zero. +If there is an error with the reading (e.g., the selected sensor is wrong) all values will return as zero. ```python #DHT sensor example diff --git a/setup.py b/setup.py index 5ed9934..d4bbef4 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="arduino-python3", - version="0.3", + version="0.4", install_requires=['pyserial'], author="Morten Kals", author_email="morten@kals.no", @@ -13,7 +13,7 @@ bridge for communicating with Arduino microcontroller boards. Extended to work with Python 3", long_description=long_description, long_description_content_type="text/markdown", - url='https://github.com/mkals/Python-Arduino-Command-API', + url='https://github.com/mkals/Arduino-Python3-Command-API', packages=['Arduino'], license='MIT', ) diff --git a/sketches/prototype/prototype.ino b/sketches/prototype/prototype.ino index f364e6d..418c297 100644 --- a/sketches/prototype/prototype.ino +++ b/sketches/prototype/prototype.ino @@ -4,6 +4,11 @@ #include #include +void Version(){ + Serial.println(F("V0.4")); +} + + SoftwareSerial *sserial = NULL; Servo servos[8]; int servo_pins[] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -26,10 +31,6 @@ void split(String results[], int len, String input, char spChar) { } } -void Version(){ - Serial.println("version"); -} - uint8_t readCapacitivePin(String data) { int pinToMeasure = Str2int(data); // readCapacitivePin From 90ebb13ea73541d58b181c2a427e75d9593e59a1 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Sun, 21 Apr 2019 16:01:58 -0700 Subject: [PATCH 11/18] Removed test file --- Arduino/temp.py | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 Arduino/temp.py diff --git a/Arduino/temp.py b/Arduino/temp.py deleted file mode 100644 index ae20e1f..0000000 --- a/Arduino/temp.py +++ /dev/null @@ -1,25 +0,0 @@ - -from arduino import Arduino - -board = Arduino() - -#from Arduino import Arduino -#import time -# -#PORT_NAME = '/dev/tty.usbserial-1410' # MUST BE UPDATED TO USE THE CORRECT PORT -#PIN_SENSE = 12 # pin where ultrasic sensor is connected -# -## connect to Arduino -#board = Arduino(port=PORT_NAME) -#print('Connected') -# -#try: -# while True: -# # make distance measurement -# pulseTime = board.pulseIn_set(PIN_SENSE, 'HIGH') -# print(pulseTime) -# -# time.sleep(1) # delay to keep UART bus for getting overloaded -# -#except KeyboardInterrupt: -# board.close() # close serial connection \ No newline at end of file From e2444761bd2e8e116d4f6dcf6acf8328313d4115 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Sun, 21 Apr 2019 18:25:37 -0700 Subject: [PATCH 12/18] Big fix for automated connection --- Arduino/arduino.py | 47 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index f7f7d58..fcfe3d3 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -79,16 +79,25 @@ def find_port(baud, timeout): version = get_version(sr) if version != libraryVersion: - if version[0] == 'V' or version == "version": - print("You need to update the version of the Arduino-Python3 ", - "library running on your Arduino. ", - "Flash the prototype sketch again.") + try: + ver = version[0] + except Exception: + ver = '' + + if ver == 'V' or version == "version": + print("You need to update the version of the Arduino-Python3", + "library running on your Arduino.") + print("The Arduino sketch is", version) + print("The Python installation is", libraryVersion) + print("Flash the prototype sketch again.") return sr - else: - log.debug('Bad version {0}. This is not a Shrimp/Arduino!'.format( - version)) - sr.close() - continue + + # established to be the wrong board + log.debug('Bad version {0}. This is not a Shrimp/Arduino!'.format( + version)) + sr.close() + continue + log.info('Using port {0}.'.format(p)) if sr: return sr @@ -121,11 +130,21 @@ def __init__(self, baud=115200, port=None, timeout=2, sr=None): sr = serial.Serial(port, baud, timeout=timeout) sr.readline() # wait til board has rebooted and is connected - # check version - if get_version(sr) != libraryVersion: - print("You need to update the version of the Arduino-Python3 ", - "library running on your Arduino. ", - "Flash the prototype sketch again.") + version = get_version(sr) + + if version != libraryVersion: + # check version + try: + ver = version[0] + except Exception: + ver = '' + + if ver == 'V' or version == "version": + print("You need to update the version of the Arduino-Python3", + "library running on your Arduino.") + print("The Arduino sketch is", version) + print("The Python installation is", libraryVersion) + print("Flash the prototype sketch again.") sr.flush() self.sr = sr From e88c87e73e3e2d3df35c46850ac66e4504991099 Mon Sep 17 00:00:00 2001 From: Bryan Poteryko Date: Thu, 2 May 2019 16:02:38 -0700 Subject: [PATCH 13/18] Added SSD1306 display support. Can now send text to a connected display via displayText(text, fontsize).I have commented out the servo control code so that it doesn't fill up the Arduino Nano's memory. --- Arduino/arduino.py | 70 ++++++++++++++++ sketches/prototype/prototype.ino | 137 +++++++++++++++++++++---------- 2 files changed, 162 insertions(+), 45 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index fcfe3d3..3bcc0fb 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -496,7 +496,77 @@ def dht(self, pin, module = 0): except: return None + # Bryan's attempt at extending this package's functionality to include the ability to write text to the Arduino screen. + # I will ignore drawing anything fancy, and just focus on displaying text. If fancy drawings are seen to be useful, they can be added later. + # There will be several functions. One to clear and reset the display, + # one to set up the display to draw things, and one to actually draw the text (the most resource-intensive, so should be called at the end) + + + # Let's do this. + + def setupDisplay(self): + """ + Sets up a I2C-connected SSD1306 display to receive data. This sends + the command 'scs' to the Arduino (SCreen Setup). + + + Inputs: (TODO) + width: width of the display, in pixels. + height: height of the display, in pixels. + + """ + + width = 128 + height = 32 + + cmd_str = build_cmd_str("scs", (width, height)) + try: + self.sr.write(str.encode(cmd_str)) + self.sr.flush() + except: + pass + # not sure what this does + # rd = self.sr.readline().decode("utf-8").replace("\r\n", "") + # try: + # return int(rd) + # except: + # return 0 + + + def clearDisplay(self): + """ + Clears the connected display from its previously-set values. Should + be called before writing anything new to the display. + + This sends the command 'scc' to the Arduino (SCreen Clear). + """ + + cmd_str = build_cmd_str("scc") + try: + self.sr.write(str.encode(cmd_str)) + self.sr.flush() + except: + pass + + + def displayText(self, text, fontsize=1): + """ + Sets a string of text to be displayed on the connected SSD1306 + display. It sends the command 'dst' to the Arduino. + + Inputs: + text: A string, containing the characters to be displayed. + fontsize: A single integer value, adjusts the size of the + characters. Please only pass numbers between 1 and 9. + """ + + cmd_str = build_cmd_str("dst", (text, fontsize)) + try: + self.sr.write(str.encode(cmd_str)) + self.sr.flush() + except: + pass class Shrimp(Arduino): diff --git a/sketches/prototype/prototype.ino b/sketches/prototype/prototype.ino index 418c297..870b443 100644 --- a/sketches/prototype/prototype.ino +++ b/sketches/prototype/prototype.ino @@ -1,16 +1,20 @@ #include #include -#include +//#include #include #include +// NOTE: Requires new libraries for screens: +#include +#include + void Version(){ Serial.println(F("V0.4")); } SoftwareSerial *sserial = NULL; -Servo servos[8]; +//Servo servos[8]; int servo_pins[] = {0, 0, 0, 0, 0, 0, 0, 0}; boolean connected = false; @@ -249,59 +253,59 @@ void pulseInSHandler(String data){ } void SV_add(String data) { - String sdata[3]; - split(sdata,3,data,'%'); - int pin = Str2int(sdata[0]); - int min = Str2int(sdata[1]); - int max = Str2int(sdata[2]); - int pos = -1; - for (int i = 0; i<8;i++) { - if (servo_pins[i] == pin) { //reset in place - servos[pos].detach(); - servos[pos].attach(pin, min, max); - servo_pins[pos] = pin; - Serial.println(pos); - return; - } - } - for (int i = 0; i<8;i++) { - if (servo_pins[i] == 0) {pos = i;break;} // find spot in servo array - } - if (pos == -1) {;} //no array position available! - else { - servos[pos].attach(pin, min, max); - servo_pins[pos] = pin; - Serial.println(pos); - } +// String sdata[3]; +// split(sdata,3,data,'%'); +// int pin = Str2int(sdata[0]); +// int min = Str2int(sdata[1]); +// int max = Str2int(sdata[2]); +// int pos = -1; +// for (int i = 0; i<8;i++) { +// if (servo_pins[i] == pin) { //reset in place +// servos[pos].detach(); +// servos[pos].attach(pin, min, max); +// servo_pins[pos] = pin; +// Serial.println(pos); +// return; +// } +// } +// for (int i = 0; i<8;i++) { +// if (servo_pins[i] == 0) {pos = i;break;} // find spot in servo array +// } +// if (pos == -1) {;} //no array position available! +// else { +// servos[pos].attach(pin, min, max); +// servo_pins[pos] = pin; +// Serial.println(pos); +// } } void SV_remove(String data) { - int pos = Str2int(data); - servos[pos].detach(); - servo_pins[pos] = 0; +// int pos = Str2int(data); +// servos[pos].detach(); +// servo_pins[pos] = 0; } void SV_read(String data) { - int pos = Str2int(data); - int angle; - angle = servos[pos].read(); - Serial.println(angle); +// int pos = Str2int(data); +// int angle; +// angle = servos[pos].read(); +// Serial.println(angle); } void SV_write(String data) { - String sdata[2]; - split(sdata,2,data,'%'); - int pos = Str2int(sdata[0]); - int angle = Str2int(sdata[1]); - servos[pos].write(angle); +// String sdata[2]; +// split(sdata,2,data,'%'); +// int pos = Str2int(sdata[0]); +// int angle = Str2int(sdata[1]); +// servos[pos].write(angle); } void SV_write_ms(String data) { - String sdata[2]; - split(sdata,2,data,'%'); - int pos = Str2int(sdata[0]); - int uS = Str2int(sdata[1]); - servos[pos].writeMicroseconds(uS); +// String sdata[2]; +// split(sdata,2,data,'%'); +// int pos = Str2int(sdata[0]); +// int uS = Str2int(sdata[1]); +// servos[pos].writeMicroseconds(uS); } void sizeEEPROM() { @@ -324,13 +328,13 @@ DHT dhtSensor(dhtSensorPin, DHT11); void dht(String data) { String sdata[2]; - split(sdata, 2, data, '%'); int dataPin = sdata[0].toInt(); int sensorNumber = sdata[1].toInt(); int sensorType = DHT11; // assume DHT11 as default if (sensorNumber == 1) { - sensorType = DHT12; + // split(sdata, 2, data, '%'); + sensorType = DHT12; } else if (sensorNumber == 2) { sensorType = DHT21; } else if (sensorNumber == 2) { @@ -361,6 +365,45 @@ void dht(String data) { Serial.println(String(h) + "&" + String(t) + "&" + String(hic)); } + +// TODO: Fix the stuttering problem being caused by the program calling the display parameter multiple times. + +// A large function to set up the display, clear it from previously, set a line(s) of text, and write it. +// TODO: I was unable to break this apart into different functions to play around with in Python, due to issues with variable scope. I will come back to this. +void displayText(String data) { + + int screen_height = 32; + int screen_width = 128; + + // The analog pin number connected to the reset pin of the screen (SDA). + int reset_pin = 4; + + // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins). + Adafruit_SSD1306 display(screen_width, screen_height, &Wire, 4); + + display.begin(SSD1306_SWITCHCAPVCC, 0x3C); + + // Clears previously displayed data and resets the cursor and text colour. + display.clearDisplay(); + display.setCursor(0,0); + display.setTextColor(WHITE); + + // The input data string contains the text to be written, along with %#, + // where # is the font size. This sets the font size by reading the last + // character of the input data (by default it is 1), and converting it + // to an int. Once that is done, the last two characters are deleted. + int font_size = data[data.length() - 1] - 48; + display.setTextSize(font_size); + data.remove(data.length() - 2); + + display.print(data); + + // Prints the above to the display. Relatively resource-intensive. + display.display(); + delay(50); +} + +// TODO: try a switch statement, might save memory. void SerialParser(void) { char readChar[64]; Serial.readBytesUntil(33,readChar,64); @@ -448,6 +491,10 @@ void SerialParser(void) { else if (cmd == "dht") { dht(data); } + // screen display functions go here. + else if (cmd == "dst") { + displayText(data); + } } void setup() { From a64aa908b812e0f3ae7f3e6fa1f859fba139f88e Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Thu, 2 May 2019 16:14:19 -0700 Subject: [PATCH 14/18] misc --- pypi_commands.txt | 2 + setup.py | 2 +- .../prototype_extended/prototype_extended.ino | 463 ++++++++++++++++++ 3 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 pypi_commands.txt create mode 100644 sketches/prototype_extended/prototype_extended.ino diff --git a/pypi_commands.txt b/pypi_commands.txt new file mode 100644 index 0000000..4b709a3 --- /dev/null +++ b/pypi_commands.txt @@ -0,0 +1,2 @@ +python3 setup.py sdist bdist_wheel +python3 -m twine upload dist/* diff --git a/setup.py b/setup.py index d4bbef4..6a52f2b 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="arduino-python3", - version="0.4", + version="0.4.1", install_requires=['pyserial'], author="Morten Kals", author_email="morten@kals.no", diff --git a/sketches/prototype_extended/prototype_extended.ino b/sketches/prototype_extended/prototype_extended.ino new file mode 100644 index 0000000..418c297 --- /dev/null +++ b/sketches/prototype_extended/prototype_extended.ino @@ -0,0 +1,463 @@ +#include +#include +#include +#include +#include + +void Version(){ + Serial.println(F("V0.4")); +} + + +SoftwareSerial *sserial = NULL; +Servo servos[8]; +int servo_pins[] = {0, 0, 0, 0, 0, 0, 0, 0}; +boolean connected = false; + +int Str2int (String Str_value) +{ + char buffer[10]; //max length is three units + Str_value.toCharArray(buffer, 10); + int int_value = atoi(buffer); + return int_value; +} + +void split(String results[], int len, String input, char spChar) { + String temp = input; + for (int i=0; ibegin(baud_); + Serial.println("ss OK"); +} + +void SS_write(String data) { + int len = data.length()+1; + char buffer[len]; + data.toCharArray(buffer,len); + Serial.println("ss OK"); + sserial->write(buffer); +} +void SS_read(String data) { + char c = sserial->read(); + Serial.println(c); +} + +void pulseInHandler(String data){ + int pin = Str2int(data); + long duration; + if(pin <=0){ + pinMode(-pin, INPUT); + duration = pulseIn(-pin, LOW); + }else{ + pinMode(pin, INPUT); + duration = pulseIn(pin, HIGH); + } + Serial.println(duration); +} + +void pulseInSHandler(String data){ + int pin = Str2int(data); + long duration; + if(pin <=0){ + pinMode(-pin, OUTPUT); + digitalWrite(-pin, HIGH); + delayMicroseconds(2); + digitalWrite(-pin, LOW); + delayMicroseconds(5); + digitalWrite(-pin, HIGH); + pinMode(-pin, INPUT); + duration = pulseIn(-pin, LOW); + }else{ + pinMode(pin, OUTPUT); + digitalWrite(pin, LOW); + delayMicroseconds(2); + digitalWrite(pin, HIGH); + delayMicroseconds(5); + digitalWrite(pin, LOW); + pinMode(pin, INPUT); + duration = pulseIn(pin, HIGH); + } + Serial.println(duration); +} + +void SV_add(String data) { + String sdata[3]; + split(sdata,3,data,'%'); + int pin = Str2int(sdata[0]); + int min = Str2int(sdata[1]); + int max = Str2int(sdata[2]); + int pos = -1; + for (int i = 0; i<8;i++) { + if (servo_pins[i] == pin) { //reset in place + servos[pos].detach(); + servos[pos].attach(pin, min, max); + servo_pins[pos] = pin; + Serial.println(pos); + return; + } + } + for (int i = 0; i<8;i++) { + if (servo_pins[i] == 0) {pos = i;break;} // find spot in servo array + } + if (pos == -1) {;} //no array position available! + else { + servos[pos].attach(pin, min, max); + servo_pins[pos] = pin; + Serial.println(pos); + } +} + +void SV_remove(String data) { + int pos = Str2int(data); + servos[pos].detach(); + servo_pins[pos] = 0; +} + +void SV_read(String data) { + int pos = Str2int(data); + int angle; + angle = servos[pos].read(); + Serial.println(angle); +} + +void SV_write(String data) { + String sdata[2]; + split(sdata,2,data,'%'); + int pos = Str2int(sdata[0]); + int angle = Str2int(sdata[1]); + servos[pos].write(angle); +} + +void SV_write_ms(String data) { + String sdata[2]; + split(sdata,2,data,'%'); + int pos = Str2int(sdata[0]); + int uS = Str2int(sdata[1]); + servos[pos].writeMicroseconds(uS); +} + +void sizeEEPROM() { + Serial.println(E2END + 1); +} + +void EEPROMHandler(int mode, String data) { + String sdata[2]; + split(sdata, 2, data, '%'); + if (mode == 0) { + EEPROM.write(Str2int(sdata[0]), Str2int(sdata[1])); + } else { + Serial.println(EEPROM.read(Str2int(sdata[0]))); + } +} + +int dhtSensorPin = -1; +DHT dhtSensor(dhtSensorPin, DHT11); + +void dht(String data) { + + String sdata[2]; + split(sdata, 2, data, '%'); + int dataPin = sdata[0].toInt(); + int sensorNumber = sdata[1].toInt(); + + int sensorType = DHT11; // assume DHT11 as default + if (sensorNumber == 1) { + sensorType = DHT12; + } else if (sensorNumber == 2) { + sensorType = DHT21; + } else if (sensorNumber == 2) { + sensorType = DHT22; + } else if (sensorNumber == 2) { + sensorType = AM2301; + } + + // do not initialize new sensor if we are reading repeatedly from same sensor + if (dataPin != dhtSensorPin) { + dhtSensorPin = dataPin; + dhtSensor = DHT(dataPin, sensorType); + dhtSensor.begin(); + } + + // Reading temperature or humidity takes about 250 milliseconds! + // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) + float h = dhtSensor.readHumidity(); + // Read temperature as Celsius (the default) + float t = dhtSensor.readTemperature(); + + if (isnan(h) || isnan(t)) { + Serial.println("0&0&0"); + return; + } + + float hic = dhtSensor.computeHeatIndex(t, h, false); + Serial.println(String(h) + "&" + String(t) + "&" + String(hic)); +} + +void SerialParser(void) { + char readChar[64]; + Serial.readBytesUntil(33,readChar,64); + String read_ = String(readChar); + //Serial.println(readChar); + int idx1 = read_.indexOf('%'); + int idx2 = read_.indexOf('$'); + // separate command from associated data + String cmd = read_.substring(1,idx1); + String data = read_.substring(idx1+1,idx2); + + // determine command sent + if (cmd == "dw") { + DigitalHandler(1, data); + } + else if (cmd == "dr") { + DigitalHandler(0, data); + } + else if (cmd == "aw") { + AnalogHandler(1, data); + } + else if (cmd == "ar") { + AnalogHandler(0, data); + } + else if (cmd == "pm") { + ConfigurePinHandler(data); + } + else if (cmd == "ps") { + pulseInSHandler(data); + } + else if (cmd == "pi") { + pulseInHandler(data); + } + else if (cmd == "ss") { + SS_set(data); + } + else if (cmd == "sw") { + SS_write(data); + } + else if (cmd == "sr") { + SS_read(data); + } + else if (cmd == "sva") { + SV_add(data); + } + else if (cmd == "svr") { + SV_read(data); + } + else if (cmd == "svw") { + SV_write(data); + } + else if (cmd == "svwm") { + SV_write_ms(data); + } + else if (cmd == "svd") { + SV_remove(data); + } + else if (cmd == "version") { + Version(); + } + else if (cmd == "to") { + Tone(data); + } + else if (cmd == "nto") { + ToneNo(data); + } + else if (cmd == "cap") { + readCapacitivePin(data); + } + else if (cmd == "so") { + shiftOutHandler(data); + } + else if (cmd == "si") { + shiftInHandler(data); + } + else if (cmd == "eewr") { + EEPROMHandler(0, data); + } + else if (cmd == "eer") { + EEPROMHandler(1, data); + } + else if (cmd == "sz") { + sizeEEPROM(); + } + else if (cmd == "dht") { + dht(data); + } +} + +void setup() { + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + Serial.println("connected"); +} + +void loop() { + SerialParser(); +} From 87ed24da88f4947a42c8d235b14228417688cee7 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Thu, 2 May 2019 16:27:49 -0700 Subject: [PATCH 15/18] Added display support --- Arduino/arduino.py | 10 +- README.md | 4 + setup.py | 2 +- sketches/prototype/prototype.ino | 128 +++++++-------- .../prototype_simple.ino} | 152 ++++++------------ 5 files changed, 127 insertions(+), 169 deletions(-) rename sketches/{prototype_extended/prototype_extended.ino => prototype_simple/prototype_simple.ino} (78%) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index 3bcc0fb..0f98991 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -12,7 +12,7 @@ else: import glob -libraryVersion = 'V0.4' +libraryVersion = 'V0.5' log = logging.getLogger(__name__) @@ -499,7 +499,7 @@ def dht(self, pin, module = 0): # Bryan's attempt at extending this package's functionality to include the ability to write text to the Arduino screen. # I will ignore drawing anything fancy, and just focus on displaying text. If fancy drawings are seen to be useful, they can be added later. - # There will be several functions. One to clear and reset the display, + # There will be several functions. One to clear and reset the display, # one to set up the display to draw things, and one to actually draw the text (the most resource-intensive, so should be called at the end) @@ -507,7 +507,7 @@ def dht(self, pin, module = 0): def setupDisplay(self): """ - Sets up a I2C-connected SSD1306 display to receive data. This sends + Sets up a I2C-connected SSD1306 display to receive data. This sends the command 'scs' to the Arduino (SCreen Setup). @@ -552,12 +552,12 @@ def clearDisplay(self): def displayText(self, text, fontsize=1): """ - Sets a string of text to be displayed on the connected SSD1306 + Sets a string of text to be displayed on the connected SSD1306 display. It sends the command 'dst' to the Arduino. Inputs: text: A string, containing the characters to be displayed. - fontsize: A single integer value, adjusts the size of the + fontsize: A single integer value, adjusts the size of the characters. Please only pass numbers between 1 and 9. """ diff --git a/README.md b/README.md index 15255eb..3ac6dca 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,10 @@ print(board.EEPROM.read(location)) print('EEPROM size {size}'.format(size=board.EEPROM.size())) ``` +**Screen** +Display text on an LCD screen. +Use the function displayText(text, fontSize = 1) to display a string on the screen. + **DHT** - `Arduino.dht(pin, module)` reads sensor values from the DHT sensor connected at the specified pin. diff --git a/setup.py b/setup.py index 6a52f2b..a53ccaf 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="arduino-python3", - version="0.4.1", + version="0.5", install_requires=['pyserial'], author="Morten Kals", author_email="morten@kals.no", diff --git a/sketches/prototype/prototype.ino b/sketches/prototype/prototype.ino index 870b443..17d74b8 100644 --- a/sketches/prototype/prototype.ino +++ b/sketches/prototype/prototype.ino @@ -9,7 +9,7 @@ #include void Version(){ - Serial.println(F("V0.4")); + Serial.println(F("V0.5")); } @@ -88,7 +88,7 @@ uint8_t readCapacitivePin(String data) { else if (*pin & bitmask) { cycles = 16;} // Discharge the pin again by setting it low and output - // It's important to leave the pins low if you want to + // It's important to leave the pins low if you want to // be able to touch more than 1 sensor at a time - if // the sensor is left pulled high, when you touch // two sensors, your body will transfer the charge between @@ -118,12 +118,12 @@ void Tone(String data){ delay(pause); noTone(pin); } -} +} void ToneNo(String data){ int pin = Str2int(data); noTone(pin); -} +} void DigitalHandler(int mode, String data){ int pin = Str2int(data); @@ -161,7 +161,7 @@ void ConfigurePinHandler(String data){ } } -void shiftOutHandler(String data) { +void shiftOutHandler(String data) { String sdata[4]; split(sdata, 4, data, '%'); int dataPin = sdata[0].toInt(); @@ -207,10 +207,10 @@ void SS_write(String data) { char buffer[len]; data.toCharArray(buffer,len); Serial.println("ss OK"); - sserial->write(buffer); + sserial->write(buffer); } void SS_read(String data) { - char c = sserial->read(); + char c = sserial->read(); Serial.println(c); } @@ -219,10 +219,10 @@ void pulseInHandler(String data){ long duration; if(pin <=0){ pinMode(-pin, INPUT); - duration = pulseIn(-pin, LOW); + duration = pulseIn(-pin, LOW); }else{ pinMode(pin, INPUT); - duration = pulseIn(pin, HIGH); + duration = pulseIn(pin, HIGH); } Serial.println(duration); } @@ -238,7 +238,7 @@ void pulseInSHandler(String data){ delayMicroseconds(5); digitalWrite(-pin, HIGH); pinMode(-pin, INPUT); - duration = pulseIn(-pin, LOW); + duration = pulseIn(-pin, LOW); }else{ pinMode(pin, OUTPUT); digitalWrite(pin, LOW); @@ -247,7 +247,7 @@ void pulseInSHandler(String data){ delayMicroseconds(5); digitalWrite(pin, LOW); pinMode(pin, INPUT); - duration = pulseIn(pin, HIGH); + duration = pulseIn(pin, HIGH); } Serial.println(duration); } @@ -315,8 +315,8 @@ void sizeEEPROM() { void EEPROMHandler(int mode, String data) { String sdata[2]; split(sdata, 2, data, '%'); - if (mode == 0) { - EEPROM.write(Str2int(sdata[0]), Str2int(sdata[1])); + if (mode == 0) { + EEPROM.write(Str2int(sdata[0]), Str2int(sdata[1])); } else { Serial.println(EEPROM.read(Str2int(sdata[0]))); } @@ -326,11 +326,11 @@ int dhtSensorPin = -1; DHT dhtSensor(dhtSensorPin, DHT11); void dht(String data) { - + String sdata[2]; int dataPin = sdata[0].toInt(); int sensorNumber = sdata[1].toInt(); - + int sensorType = DHT11; // assume DHT11 as default if (sensorNumber == 1) { // split(sdata, 2, data, '%'); @@ -355,12 +355,12 @@ void dht(String data) { float h = dhtSensor.readHumidity(); // Read temperature as Celsius (the default) float t = dhtSensor.readTemperature(); - + if (isnan(h) || isnan(t)) { Serial.println("0&0&0"); return; } - + float hic = dhtSensor.computeHeatIndex(t, h, false); Serial.println(String(h) + "&" + String(t) + "&" + String(hic)); } @@ -371,26 +371,26 @@ void dht(String data) { // A large function to set up the display, clear it from previously, set a line(s) of text, and write it. // TODO: I was unable to break this apart into different functions to play around with in Python, due to issues with variable scope. I will come back to this. void displayText(String data) { - + int screen_height = 32; int screen_width = 128; - + // The analog pin number connected to the reset pin of the screen (SDA). int reset_pin = 4; // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins). - Adafruit_SSD1306 display(screen_width, screen_height, &Wire, 4); + Adafruit_SSD1306 display(screen_width, screen_height, &Wire, 4); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); - + // Clears previously displayed data and resets the cursor and text colour. display.clearDisplay(); display.setCursor(0,0); display.setTextColor(WHITE); - // The input data string contains the text to be written, along with %#, - // where # is the font size. This sets the font size by reading the last - // character of the input data (by default it is 1), and converting it + // The input data string contains the text to be written, along with %#, + // where # is the font size. This sets the font size by reading the last + // character of the input data (by default it is 1), and converting it // to an int. Once that is done, the last two characters are deleted. int font_size = data[data.length() - 1] - 48; display.setTextSize(font_size); @@ -414,64 +414,64 @@ void SerialParser(void) { // separate command from associated data String cmd = read_.substring(1,idx1); String data = read_.substring(idx1+1,idx2); - + // determine command sent if (cmd == "dw") { - DigitalHandler(1, data); + DigitalHandler(1, data); } else if (cmd == "dr") { - DigitalHandler(0, data); - } + DigitalHandler(0, data); + } else if (cmd == "aw") { - AnalogHandler(1, data); - } + AnalogHandler(1, data); + } else if (cmd == "ar") { - AnalogHandler(0, data); - } + AnalogHandler(0, data); + } else if (cmd == "pm") { - ConfigurePinHandler(data); - } + ConfigurePinHandler(data); + } else if (cmd == "ps") { - pulseInSHandler(data); - } + pulseInSHandler(data); + } else if (cmd == "pi") { - pulseInHandler(data); - } + pulseInHandler(data); + } else if (cmd == "ss") { - SS_set(data); + SS_set(data); } else if (cmd == "sw") { - SS_write(data); + SS_write(data); } else if (cmd == "sr") { - SS_read(data); - } + SS_read(data); + } else if (cmd == "sva") { - SV_add(data); - } + SV_add(data); + } else if (cmd == "svr") { - SV_read(data); - } + SV_read(data); + } else if (cmd == "svw") { - SV_write(data); - } + SV_write(data); + } else if (cmd == "svwm") { - SV_write_ms(data); - } + SV_write_ms(data); + } else if (cmd == "svd") { - SV_remove(data); - } + SV_remove(data); + } else if (cmd == "version") { - Version(); + Version(); } else if (cmd == "to") { - Tone(data); - } + Tone(data); + } else if (cmd == "nto") { - ToneNo(data); - } + ToneNo(data); + } else if (cmd == "cap") { - readCapacitivePin(data); + readCapacitivePin(data); } else if (cmd == "so") { shiftOutHandler(data); @@ -480,12 +480,12 @@ void SerialParser(void) { shiftInHandler(data); } else if (cmd == "eewr") { - EEPROMHandler(0, data); - } + EEPROMHandler(0, data); + } else if (cmd == "eer") { - EEPROMHandler(1, data); - } - else if (cmd == "sz") { + EEPROMHandler(1, data); + } + else if (cmd == "sz") { sizeEEPROM(); } else if (cmd == "dht") { @@ -498,7 +498,7 @@ void SerialParser(void) { } void setup() { - Serial.begin(115200); + Serial.begin(115200); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } diff --git a/sketches/prototype_extended/prototype_extended.ino b/sketches/prototype_simple/prototype_simple.ino similarity index 78% rename from sketches/prototype_extended/prototype_extended.ino rename to sketches/prototype_simple/prototype_simple.ino index 418c297..a89a193 100644 --- a/sketches/prototype_extended/prototype_extended.ino +++ b/sketches/prototype_simple/prototype_simple.ino @@ -2,10 +2,9 @@ #include #include #include -#include void Version(){ - Serial.println(F("V0.4")); + Serial.println(F("V0.5")); } @@ -84,7 +83,7 @@ uint8_t readCapacitivePin(String data) { else if (*pin & bitmask) { cycles = 16;} // Discharge the pin again by setting it low and output - // It's important to leave the pins low if you want to + // It's important to leave the pins low if you want to // be able to touch more than 1 sensor at a time - if // the sensor is left pulled high, when you touch // two sensors, your body will transfer the charge between @@ -114,12 +113,12 @@ void Tone(String data){ delay(pause); noTone(pin); } -} +} void ToneNo(String data){ int pin = Str2int(data); noTone(pin); -} +} void DigitalHandler(int mode, String data){ int pin = Str2int(data); @@ -157,7 +156,7 @@ void ConfigurePinHandler(String data){ } } -void shiftOutHandler(String data) { +void shiftOutHandler(String data) { String sdata[4]; split(sdata, 4, data, '%'); int dataPin = sdata[0].toInt(); @@ -203,10 +202,10 @@ void SS_write(String data) { char buffer[len]; data.toCharArray(buffer,len); Serial.println("ss OK"); - sserial->write(buffer); + sserial->write(buffer); } void SS_read(String data) { - char c = sserial->read(); + char c = sserial->read(); Serial.println(c); } @@ -215,10 +214,10 @@ void pulseInHandler(String data){ long duration; if(pin <=0){ pinMode(-pin, INPUT); - duration = pulseIn(-pin, LOW); + duration = pulseIn(-pin, LOW); }else{ pinMode(pin, INPUT); - duration = pulseIn(pin, HIGH); + duration = pulseIn(pin, HIGH); } Serial.println(duration); } @@ -234,7 +233,7 @@ void pulseInSHandler(String data){ delayMicroseconds(5); digitalWrite(-pin, HIGH); pinMode(-pin, INPUT); - duration = pulseIn(-pin, LOW); + duration = pulseIn(-pin, LOW); }else{ pinMode(pin, OUTPUT); digitalWrite(pin, LOW); @@ -243,7 +242,7 @@ void pulseInSHandler(String data){ delayMicroseconds(5); digitalWrite(pin, LOW); pinMode(pin, INPUT); - duration = pulseIn(pin, HIGH); + duration = pulseIn(pin, HIGH); } Serial.println(duration); } @@ -311,55 +310,13 @@ void sizeEEPROM() { void EEPROMHandler(int mode, String data) { String sdata[2]; split(sdata, 2, data, '%'); - if (mode == 0) { - EEPROM.write(Str2int(sdata[0]), Str2int(sdata[1])); + if (mode == 0) { + EEPROM.write(Str2int(sdata[0]), Str2int(sdata[1])); } else { Serial.println(EEPROM.read(Str2int(sdata[0]))); } } -int dhtSensorPin = -1; -DHT dhtSensor(dhtSensorPin, DHT11); - -void dht(String data) { - - String sdata[2]; - split(sdata, 2, data, '%'); - int dataPin = sdata[0].toInt(); - int sensorNumber = sdata[1].toInt(); - - int sensorType = DHT11; // assume DHT11 as default - if (sensorNumber == 1) { - sensorType = DHT12; - } else if (sensorNumber == 2) { - sensorType = DHT21; - } else if (sensorNumber == 2) { - sensorType = DHT22; - } else if (sensorNumber == 2) { - sensorType = AM2301; - } - - // do not initialize new sensor if we are reading repeatedly from same sensor - if (dataPin != dhtSensorPin) { - dhtSensorPin = dataPin; - dhtSensor = DHT(dataPin, sensorType); - dhtSensor.begin(); - } - - // Reading temperature or humidity takes about 250 milliseconds! - // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) - float h = dhtSensor.readHumidity(); - // Read temperature as Celsius (the default) - float t = dhtSensor.readTemperature(); - - if (isnan(h) || isnan(t)) { - Serial.println("0&0&0"); - return; - } - - float hic = dhtSensor.computeHeatIndex(t, h, false); - Serial.println(String(h) + "&" + String(t) + "&" + String(hic)); -} void SerialParser(void) { char readChar[64]; @@ -371,64 +328,64 @@ void SerialParser(void) { // separate command from associated data String cmd = read_.substring(1,idx1); String data = read_.substring(idx1+1,idx2); - + // determine command sent if (cmd == "dw") { - DigitalHandler(1, data); + DigitalHandler(1, data); } else if (cmd == "dr") { - DigitalHandler(0, data); - } + DigitalHandler(0, data); + } else if (cmd == "aw") { - AnalogHandler(1, data); - } + AnalogHandler(1, data); + } else if (cmd == "ar") { - AnalogHandler(0, data); - } + AnalogHandler(0, data); + } else if (cmd == "pm") { - ConfigurePinHandler(data); - } + ConfigurePinHandler(data); + } else if (cmd == "ps") { - pulseInSHandler(data); - } + pulseInSHandler(data); + } else if (cmd == "pi") { - pulseInHandler(data); - } + pulseInHandler(data); + } else if (cmd == "ss") { - SS_set(data); + SS_set(data); } else if (cmd == "sw") { - SS_write(data); + SS_write(data); } else if (cmd == "sr") { - SS_read(data); - } + SS_read(data); + } else if (cmd == "sva") { - SV_add(data); - } + SV_add(data); + } else if (cmd == "svr") { - SV_read(data); - } + SV_read(data); + } else if (cmd == "svw") { - SV_write(data); - } + SV_write(data); + } else if (cmd == "svwm") { - SV_write_ms(data); - } + SV_write_ms(data); + } else if (cmd == "svd") { - SV_remove(data); - } + SV_remove(data); + } else if (cmd == "version") { - Version(); + Version(); } else if (cmd == "to") { - Tone(data); - } + Tone(data); + } else if (cmd == "nto") { - ToneNo(data); - } + ToneNo(data); + } else if (cmd == "cap") { - readCapacitivePin(data); + readCapacitivePin(data); } else if (cmd == "so") { shiftOutHandler(data); @@ -437,21 +394,18 @@ void SerialParser(void) { shiftInHandler(data); } else if (cmd == "eewr") { - EEPROMHandler(0, data); - } + EEPROMHandler(0, data); + } else if (cmd == "eer") { - EEPROMHandler(1, data); - } - else if (cmd == "sz") { - sizeEEPROM(); + EEPROMHandler(1, data); } - else if (cmd == "dht") { - dht(data); + else if (cmd == "sz") { + sizeEEPROM(); } } void setup() { - Serial.begin(115200); + Serial.begin(115200); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } From ea33b9c5dba80cc2a729ad3adb23a4c0736c0474 Mon Sep 17 00:00:00 2001 From: Bryan Poteryko Date: Thu, 2 May 2019 20:08:39 -0700 Subject: [PATCH 16/18] Updated version numbers, quick bugfix Updated version from 0.4 to 0.5 in both files, as well as removed the unused functions in arduino.py. Also fixed a mistakenly-commented-out line introduced in the previous commit, which broke temperature readings. --- Arduino/arduino.py | 57 ++------------------------------ sketches/prototype/prototype.ino | 8 ++--- 2 files changed, 6 insertions(+), 59 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index 3bcc0fb..663a2cb 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -12,7 +12,7 @@ else: import glob -libraryVersion = 'V0.4' +libraryVersion = 'V0.5' log = logging.getLogger(__name__) @@ -496,60 +496,7 @@ def dht(self, pin, module = 0): except: return None - # Bryan's attempt at extending this package's functionality to include the ability to write text to the Arduino screen. - # I will ignore drawing anything fancy, and just focus on displaying text. If fancy drawings are seen to be useful, they can be added later. - - # There will be several functions. One to clear and reset the display, - # one to set up the display to draw things, and one to actually draw the text (the most resource-intensive, so should be called at the end) - - - # Let's do this. - - def setupDisplay(self): - """ - Sets up a I2C-connected SSD1306 display to receive data. This sends - the command 'scs' to the Arduino (SCreen Setup). - - - Inputs: (TODO) - width: width of the display, in pixels. - height: height of the display, in pixels. - - """ - - width = 128 - height = 32 - - cmd_str = build_cmd_str("scs", (width, height)) - try: - self.sr.write(str.encode(cmd_str)) - self.sr.flush() - except: - pass - # not sure what this does - # rd = self.sr.readline().decode("utf-8").replace("\r\n", "") - # try: - # return int(rd) - # except: - # return 0 - - - def clearDisplay(self): - """ - Clears the connected display from its previously-set values. Should - be called before writing anything new to the display. - - This sends the command 'scc' to the Arduino (SCreen Clear). - """ - - cmd_str = build_cmd_str("scc") - try: - self.sr.write(str.encode(cmd_str)) - self.sr.flush() - except: - pass - - + def displayText(self, text, fontsize=1): """ Sets a string of text to be displayed on the connected SSD1306 diff --git a/sketches/prototype/prototype.ino b/sketches/prototype/prototype.ino index 870b443..492377a 100644 --- a/sketches/prototype/prototype.ino +++ b/sketches/prototype/prototype.ino @@ -9,7 +9,7 @@ #include void Version(){ - Serial.println(F("V0.4")); + Serial.println(F("V0.5")); } @@ -328,13 +328,13 @@ DHT dhtSensor(dhtSensorPin, DHT11); void dht(String data) { String sdata[2]; + split(sdata, 2, data, '%'); int dataPin = sdata[0].toInt(); int sensorNumber = sdata[1].toInt(); int sensorType = DHT11; // assume DHT11 as default if (sensorNumber == 1) { - // split(sdata, 2, data, '%'); - sensorType = DHT12; + sensorType = DHT12; } else if (sensorNumber == 2) { sensorType = DHT21; } else if (sensorNumber == 2) { @@ -400,7 +400,7 @@ void displayText(String data) { // Prints the above to the display. Relatively resource-intensive. display.display(); - delay(50); + delay(100); } // TODO: try a switch statement, might save memory. From 0a481c7d6466249b726308c0d7c7e457bf6f89af Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Wed, 8 May 2019 00:15:23 -0700 Subject: [PATCH 17/18] Simplified to core Arduino --- Arduino/arduino.py | 19 +- README.md | 43 +- setup.py | 2 +- sketches/prototype/prototype.ino | 182 ++------ .../prototype_simple/prototype_simple.ino | 417 ------------------ 5 files changed, 47 insertions(+), 616 deletions(-) delete mode 100644 sketches/prototype_simple/prototype_simple.ino diff --git a/Arduino/arduino.py b/Arduino/arduino.py index d176b45..576534c 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -12,7 +12,7 @@ else: import glob -libraryVersion = 'V0.5' +libraryVersion = 'V0.6' log = logging.getLogger(__name__) @@ -497,23 +497,6 @@ def dht(self, pin, module = 0): return None - def displayText(self, text, fontsize=1): - """ - Sets a string of text to be displayed on the connected SSD1306 - display. It sends the command 'dst' to the Arduino. - - Inputs: - text: A string, containing the characters to be displayed. - fontsize: A single integer value, adjusts the size of the - characters. Please only pass numbers between 1 and 9. - """ - - cmd_str = build_cmd_str("dst", (text, fontsize)) - try: - self.sr.write(str.encode(cmd_str)) - self.sr.flush() - except: - pass class Shrimp(Arduino): diff --git a/README.md b/README.md index 3ac6dca..903cc6f 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ build install` from the source directory to install this library. ## Setup: 1. Verify that your Arduino board communicates at the baud rate specified in the -`setup()` function (line 348) in `prototype.ino`. Change it there if necessary. +`setup()` function (line 407) in `prototype.ino`. Change it there if necessary. 2. Load the `prototype.ino` sketch onto your Arduino board, using the Arduino IDE. 3. Set up some kind of serial I/O communication between the Arduino board and your computer (via physical USB cable, Bluetooth, xbee, etc. + associated drivers) @@ -192,47 +192,6 @@ print(board.EEPROM.read(location)) print('EEPROM size {size}'.format(size=board.EEPROM.size())) ``` -**Screen** -Display text on an LCD screen. -Use the function displayText(text, fontSize = 1) to display a string on the screen. - -**DHT** - -- `Arduino.dht(pin, module)` reads sensor values from the DHT sensor connected at the specified pin. - -Read data from DHT temperature and humidity sensors based on the -Adafruit [DHT sensor library](https://github.com/adafruit/DHT-sensor-library). - -Pass as arguments the pin the sensor is connected to (as an integer) and the sensor type you are using as an integer (see list below). - -There are five sensors that work with this library: -- 0 = DHT 11 (blue cage, less accurate) -- 1 = DHT 12 -- 2 = DHT 21 -- 3 = DHT 22 (white cage) -- 4 = AM2301 - -The function returns an array of three elements: -1. humidity (in %) -2. temperature (in Celsius) -3. heat index (in Celsius) - -If there is an error with the reading (e.g., the selected sensor is wrong) all values will return as zero. - -```python -#DHT sensor example -pin = 7 -sensorType = 0 - -data = board.dht(pin, sensorType) -[humidity, temperature, heatIndex] = data - -reply = "Humidity = " + str(humidity) + " % \t" -reply += "Temperature = " + str(temperature) + " ˙C \t" -reply += "Heat Index = " + str(heatIndex) + " ˙C" - -print(reply) -``` **Misc** diff --git a/setup.py b/setup.py index a53ccaf..074671c 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="arduino-python3", - version="0.5", + version="0.6", install_requires=['pyserial'], author="Morten Kals", author_email="morten@kals.no", diff --git a/sketches/prototype/prototype.ino b/sketches/prototype/prototype.ino index 06a23a4..9170196 100644 --- a/sketches/prototype/prototype.ino +++ b/sketches/prototype/prototype.ino @@ -1,20 +1,15 @@ #include #include -//#include +#include #include -#include - -// NOTE: Requires new libraries for screens: -#include -#include void Version(){ - Serial.println(F("V0.5")); + Serial.println(F("V0.6")); } SoftwareSerial *sserial = NULL; -//Servo servos[8]; +Servo servos[8]; int servo_pins[] = {0, 0, 0, 0, 0, 0, 0, 0}; boolean connected = false; @@ -253,59 +248,59 @@ void pulseInSHandler(String data){ } void SV_add(String data) { -// String sdata[3]; -// split(sdata,3,data,'%'); -// int pin = Str2int(sdata[0]); -// int min = Str2int(sdata[1]); -// int max = Str2int(sdata[2]); -// int pos = -1; -// for (int i = 0; i<8;i++) { -// if (servo_pins[i] == pin) { //reset in place -// servos[pos].detach(); -// servos[pos].attach(pin, min, max); -// servo_pins[pos] = pin; -// Serial.println(pos); -// return; -// } -// } -// for (int i = 0; i<8;i++) { -// if (servo_pins[i] == 0) {pos = i;break;} // find spot in servo array -// } -// if (pos == -1) {;} //no array position available! -// else { -// servos[pos].attach(pin, min, max); -// servo_pins[pos] = pin; -// Serial.println(pos); -// } + String sdata[3]; + split(sdata,3,data,'%'); + int pin = Str2int(sdata[0]); + int min = Str2int(sdata[1]); + int max = Str2int(sdata[2]); + int pos = -1; + for (int i = 0; i<8;i++) { + if (servo_pins[i] == pin) { //reset in place + servos[pos].detach(); + servos[pos].attach(pin, min, max); + servo_pins[pos] = pin; + Serial.println(pos); + return; + } + } + for (int i = 0; i<8;i++) { + if (servo_pins[i] == 0) {pos = i;break;} // find spot in servo array + } + if (pos == -1) {;} //no array position available! + else { + servos[pos].attach(pin, min, max); + servo_pins[pos] = pin; + Serial.println(pos); + } } void SV_remove(String data) { -// int pos = Str2int(data); -// servos[pos].detach(); -// servo_pins[pos] = 0; + int pos = Str2int(data); + servos[pos].detach(); + servo_pins[pos] = 0; } void SV_read(String data) { -// int pos = Str2int(data); -// int angle; -// angle = servos[pos].read(); -// Serial.println(angle); + int pos = Str2int(data); + int angle; + angle = servos[pos].read(); + Serial.println(angle); } void SV_write(String data) { -// String sdata[2]; -// split(sdata,2,data,'%'); -// int pos = Str2int(sdata[0]); -// int angle = Str2int(sdata[1]); -// servos[pos].write(angle); + String sdata[2]; + split(sdata,2,data,'%'); + int pos = Str2int(sdata[0]); + int angle = Str2int(sdata[1]); + servos[pos].write(angle); } void SV_write_ms(String data) { -// String sdata[2]; -// split(sdata,2,data,'%'); -// int pos = Str2int(sdata[0]); -// int uS = Str2int(sdata[1]); -// servos[pos].writeMicroseconds(uS); + String sdata[2]; + split(sdata,2,data,'%'); + int pos = Str2int(sdata[0]); + int uS = Str2int(sdata[1]); + servos[pos].writeMicroseconds(uS); } void sizeEEPROM() { @@ -322,88 +317,6 @@ void EEPROMHandler(int mode, String data) { } } -int dhtSensorPin = -1; -DHT dhtSensor(dhtSensorPin, DHT11); - -void dht(String data) { - - String sdata[2]; - split(sdata, 2, data, '%'); - int dataPin = sdata[0].toInt(); - int sensorNumber = sdata[1].toInt(); - - int sensorType = DHT11; // assume DHT11 as default - if (sensorNumber == 1) { - sensorType = DHT12; - } else if (sensorNumber == 2) { - sensorType = DHT21; - } else if (sensorNumber == 2) { - sensorType = DHT22; - } else if (sensorNumber == 2) { - sensorType = AM2301; - } - - // do not initialize new sensor if we are reading repeatedly from same sensor - if (dataPin != dhtSensorPin) { - dhtSensorPin = dataPin; - dhtSensor = DHT(dataPin, sensorType); - dhtSensor.begin(); - } - - // Reading temperature or humidity takes about 250 milliseconds! - // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) - float h = dhtSensor.readHumidity(); - // Read temperature as Celsius (the default) - float t = dhtSensor.readTemperature(); - - if (isnan(h) || isnan(t)) { - Serial.println("0&0&0"); - return; - } - - float hic = dhtSensor.computeHeatIndex(t, h, false); - Serial.println(String(h) + "&" + String(t) + "&" + String(hic)); -} - - -// TODO: Fix the stuttering problem being caused by the program calling the display parameter multiple times. - -// A large function to set up the display, clear it from previously, set a line(s) of text, and write it. -// TODO: I was unable to break this apart into different functions to play around with in Python, due to issues with variable scope. I will come back to this. -void displayText(String data) { - - int screen_height = 32; - int screen_width = 128; - - // The analog pin number connected to the reset pin of the screen (SDA). - int reset_pin = 4; - - // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins). - Adafruit_SSD1306 display(screen_width, screen_height, &Wire, 4); - - display.begin(SSD1306_SWITCHCAPVCC, 0x3C); - - // Clears previously displayed data and resets the cursor and text colour. - display.clearDisplay(); - display.setCursor(0,0); - display.setTextColor(WHITE); - - // The input data string contains the text to be written, along with %#, - // where # is the font size. This sets the font size by reading the last - // character of the input data (by default it is 1), and converting it - // to an int. Once that is done, the last two characters are deleted. - int font_size = data[data.length() - 1] - 48; - display.setTextSize(font_size); - data.remove(data.length() - 2); - - display.print(data); - - // Prints the above to the display. Relatively resource-intensive. - display.display(); - delay(100); -} - -// TODO: try a switch statement, might save memory. void SerialParser(void) { char readChar[64]; Serial.readBytesUntil(33,readChar,64); @@ -488,13 +401,6 @@ void SerialParser(void) { else if (cmd == "sz") { sizeEEPROM(); } - else if (cmd == "dht") { - dht(data); - } - // screen display functions go here. - else if (cmd == "dst") { - displayText(data); - } } void setup() { diff --git a/sketches/prototype_simple/prototype_simple.ino b/sketches/prototype_simple/prototype_simple.ino deleted file mode 100644 index a89a193..0000000 --- a/sketches/prototype_simple/prototype_simple.ino +++ /dev/null @@ -1,417 +0,0 @@ -#include -#include -#include -#include - -void Version(){ - Serial.println(F("V0.5")); -} - - -SoftwareSerial *sserial = NULL; -Servo servos[8]; -int servo_pins[] = {0, 0, 0, 0, 0, 0, 0, 0}; -boolean connected = false; - -int Str2int (String Str_value) -{ - char buffer[10]; //max length is three units - Str_value.toCharArray(buffer, 10); - int int_value = atoi(buffer); - return int_value; -} - -void split(String results[], int len, String input, char spChar) { - String temp = input; - for (int i=0; ibegin(baud_); - Serial.println("ss OK"); -} - -void SS_write(String data) { - int len = data.length()+1; - char buffer[len]; - data.toCharArray(buffer,len); - Serial.println("ss OK"); - sserial->write(buffer); -} -void SS_read(String data) { - char c = sserial->read(); - Serial.println(c); -} - -void pulseInHandler(String data){ - int pin = Str2int(data); - long duration; - if(pin <=0){ - pinMode(-pin, INPUT); - duration = pulseIn(-pin, LOW); - }else{ - pinMode(pin, INPUT); - duration = pulseIn(pin, HIGH); - } - Serial.println(duration); -} - -void pulseInSHandler(String data){ - int pin = Str2int(data); - long duration; - if(pin <=0){ - pinMode(-pin, OUTPUT); - digitalWrite(-pin, HIGH); - delayMicroseconds(2); - digitalWrite(-pin, LOW); - delayMicroseconds(5); - digitalWrite(-pin, HIGH); - pinMode(-pin, INPUT); - duration = pulseIn(-pin, LOW); - }else{ - pinMode(pin, OUTPUT); - digitalWrite(pin, LOW); - delayMicroseconds(2); - digitalWrite(pin, HIGH); - delayMicroseconds(5); - digitalWrite(pin, LOW); - pinMode(pin, INPUT); - duration = pulseIn(pin, HIGH); - } - Serial.println(duration); -} - -void SV_add(String data) { - String sdata[3]; - split(sdata,3,data,'%'); - int pin = Str2int(sdata[0]); - int min = Str2int(sdata[1]); - int max = Str2int(sdata[2]); - int pos = -1; - for (int i = 0; i<8;i++) { - if (servo_pins[i] == pin) { //reset in place - servos[pos].detach(); - servos[pos].attach(pin, min, max); - servo_pins[pos] = pin; - Serial.println(pos); - return; - } - } - for (int i = 0; i<8;i++) { - if (servo_pins[i] == 0) {pos = i;break;} // find spot in servo array - } - if (pos == -1) {;} //no array position available! - else { - servos[pos].attach(pin, min, max); - servo_pins[pos] = pin; - Serial.println(pos); - } -} - -void SV_remove(String data) { - int pos = Str2int(data); - servos[pos].detach(); - servo_pins[pos] = 0; -} - -void SV_read(String data) { - int pos = Str2int(data); - int angle; - angle = servos[pos].read(); - Serial.println(angle); -} - -void SV_write(String data) { - String sdata[2]; - split(sdata,2,data,'%'); - int pos = Str2int(sdata[0]); - int angle = Str2int(sdata[1]); - servos[pos].write(angle); -} - -void SV_write_ms(String data) { - String sdata[2]; - split(sdata,2,data,'%'); - int pos = Str2int(sdata[0]); - int uS = Str2int(sdata[1]); - servos[pos].writeMicroseconds(uS); -} - -void sizeEEPROM() { - Serial.println(E2END + 1); -} - -void EEPROMHandler(int mode, String data) { - String sdata[2]; - split(sdata, 2, data, '%'); - if (mode == 0) { - EEPROM.write(Str2int(sdata[0]), Str2int(sdata[1])); - } else { - Serial.println(EEPROM.read(Str2int(sdata[0]))); - } -} - - -void SerialParser(void) { - char readChar[64]; - Serial.readBytesUntil(33,readChar,64); - String read_ = String(readChar); - //Serial.println(readChar); - int idx1 = read_.indexOf('%'); - int idx2 = read_.indexOf('$'); - // separate command from associated data - String cmd = read_.substring(1,idx1); - String data = read_.substring(idx1+1,idx2); - - // determine command sent - if (cmd == "dw") { - DigitalHandler(1, data); - } - else if (cmd == "dr") { - DigitalHandler(0, data); - } - else if (cmd == "aw") { - AnalogHandler(1, data); - } - else if (cmd == "ar") { - AnalogHandler(0, data); - } - else if (cmd == "pm") { - ConfigurePinHandler(data); - } - else if (cmd == "ps") { - pulseInSHandler(data); - } - else if (cmd == "pi") { - pulseInHandler(data); - } - else if (cmd == "ss") { - SS_set(data); - } - else if (cmd == "sw") { - SS_write(data); - } - else if (cmd == "sr") { - SS_read(data); - } - else if (cmd == "sva") { - SV_add(data); - } - else if (cmd == "svr") { - SV_read(data); - } - else if (cmd == "svw") { - SV_write(data); - } - else if (cmd == "svwm") { - SV_write_ms(data); - } - else if (cmd == "svd") { - SV_remove(data); - } - else if (cmd == "version") { - Version(); - } - else if (cmd == "to") { - Tone(data); - } - else if (cmd == "nto") { - ToneNo(data); - } - else if (cmd == "cap") { - readCapacitivePin(data); - } - else if (cmd == "so") { - shiftOutHandler(data); - } - else if (cmd == "si") { - shiftInHandler(data); - } - else if (cmd == "eewr") { - EEPROMHandler(0, data); - } - else if (cmd == "eer") { - EEPROMHandler(1, data); - } - else if (cmd == "sz") { - sizeEEPROM(); - } -} - -void setup() { - Serial.begin(115200); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } - Serial.println("connected"); -} - -void loop() { - SerialParser(); -} From 4e5e0f8cc23d520050618c7d053ea80b8b8a0719 Mon Sep 17 00:00:00 2001 From: Morten Kals Date: Wed, 8 May 2019 00:17:43 -0700 Subject: [PATCH 18/18] Removed dht function --- Arduino/arduino.py | 51 ---------------------------------------------- 1 file changed, 51 deletions(-) diff --git a/Arduino/arduino.py b/Arduino/arduino.py index 576534c..e76a5b5 100755 --- a/Arduino/arduino.py +++ b/Arduino/arduino.py @@ -448,57 +448,6 @@ def shiftIn(self, dataPin, clockPin, pinOrder): return int(rd) - def dht(self, pin, module = 0): - """ - Read data from dht temperature and humidity sensors based on the - Adafruit DHT sensor library. - https://github.com/adafruit/DHT-sensor-library - - Guide for using library: - https://learn.adafruit.com/dht/using-a-dhtxx-sensor - - There are five sensors that work with this library: - - DHT 11: blue cage, less accurate - - DHT 12: - - DHT 21: - - DHT 22: white cage - - AM2301: - Input: - pin (int): pin for data - module (int): 0 = DHT 11 (default), - 1 = DHT 12, - 2 = DHT 21, - 3 = DHT 22, - 4 = AM2301 - Output: - [float, float, float] in the format: - [ humidity in %, - temperature in celcius, - heat index in celcius ] - """ - try: - if not (0 <= module <= 4): - print("unknown module, must be in range 0 to 4. Using 0 (DHT 11).") # raise exception - except: - module = 0 - print("module must be spesified using an integer. Using 0 (DHT 11).") - - cmd_str = build_cmd_str("dht", (pin, module,)) - try: - self.sr.write(str.encode(cmd_str)) - self.sr.flush() - except: - pass - rd = self.sr.readline().decode("utf-8").replace("\r\n", "") - try: - strings = rd.split("&") - return [float(s) for s in strings] - except: - return None - - - - class Shrimp(Arduino): def __init__(self):