Simplified to core Arduino

This commit is contained in:
Morten Kals
2019-05-08 00:15:23 -07:00
parent 2ab7539fed
commit 0a481c7d64
5 changed files with 47 additions and 616 deletions

View File

@@ -12,7 +12,7 @@ if sys.platform.startswith('win'):
else:
import glob
libraryVersion = 'V0.5'
libraryVersion = 'V0.6'
log = logging.getLogger(__name__)
@@ -497,23 +497,6 @@ class Arduino(object):
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):

View File

@@ -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**

View File

@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="arduino-python3",
version="0.5",
version="0.6",
install_requires=['pyserial'],
author="Morten Kals",
author_email="morten@kals.no",

View File

@@ -1,20 +1,15 @@
#include <SoftwareSerial.h>
#include <Wire.h>
//#include <Servo.h>
#include <Servo.h>
#include <EEPROM.h>
#include <DHT.h>
// NOTE: Requires new libraries for screens:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
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() {

View File

@@ -1,417 +0,0 @@
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Servo.h>
#include <EEPROM.h>
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; i<len; i++) {
int idx = temp.indexOf(spChar);
results[i] = temp.substring(0,idx);
temp = temp.substring(idx+1);
}
}
uint8_t readCapacitivePin(String data) {
int pinToMeasure = Str2int(data);
// readCapacitivePin
// Input: Arduino pin number
// Output: A number, from 0 to 17 expressing
// how much capacitance is on the pin
// When you touch the pin, or whatever you have
// attached to it, the number will get higher
// http://playground.arduino.cc/Code/CapacitiveSensor
//
// Variables used to translate from Arduino to AVR pin naming
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;
// Here we translate the input pin number from
// Arduino pin number to the AVR PORT, PIN, DDR,
// and which bit of those registers we care about.
byte bitmask;
port = portOutputRegister(digitalPinToPort(pinToMeasure));
ddr = portModeRegister(digitalPinToPort(pinToMeasure));
bitmask = digitalPinToBitMask(pinToMeasure);
pin = portInputRegister(digitalPinToPort(pinToMeasure));
// Discharge the pin first by setting it low and output
*port &= ~(bitmask);
*ddr |= bitmask;
delay(1);
// Make the pin an input with the internal pull-up on
*ddr &= ~(bitmask);
*port |= bitmask;
// Now see how long the pin to get pulled up. This manual unrolling of the loop
// decreases the number of hardware cycles between each read of the pin,
// thus increasing sensitivity.
uint8_t cycles = 17;
if (*pin & bitmask) { cycles = 0;}
else if (*pin & bitmask) { cycles = 1;}
else if (*pin & bitmask) { cycles = 2;}
else if (*pin & bitmask) { cycles = 3;}
else if (*pin & bitmask) { cycles = 4;}
else if (*pin & bitmask) { cycles = 5;}
else if (*pin & bitmask) { cycles = 6;}
else if (*pin & bitmask) { cycles = 7;}
else if (*pin & bitmask) { cycles = 8;}
else if (*pin & bitmask) { cycles = 9;}
else if (*pin & bitmask) { cycles = 10;}
else if (*pin & bitmask) { cycles = 11;}
else if (*pin & bitmask) { cycles = 12;}
else if (*pin & bitmask) { cycles = 13;}
else if (*pin & bitmask) { cycles = 14;}
else if (*pin & bitmask) { cycles = 15;}
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
// 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
// sensors.
*port &= ~(bitmask);
*ddr |= bitmask;
//return cycles;
Serial.println(cycles);
}
void Tone(String data){
int idx = data.indexOf('%');
int len = Str2int(data.substring(0,idx));
String data2 = data.substring(idx+1);
int idx2 = data2.indexOf('%');
int pin = Str2int(data2.substring(0,idx2));
String data3 = data2.substring(idx2+1);
String melody[len*2];
split(melody,len*2,data3,'%');
for (int thisNote = 0; thisNote < len; thisNote++) {
int noteDuration = 1000/Str2int(melody[thisNote+len]);
int note = Str2int(melody[thisNote]);
tone(pin, note, noteDuration);
int pause = noteDuration * 1.30;
delay(pause);
noTone(pin);
}
}
void ToneNo(String data){
int pin = Str2int(data);
noTone(pin);
}
void DigitalHandler(int mode, String data){
int pin = Str2int(data);
if(mode<=0){ //read
Serial.println(digitalRead(pin));
}else{
if(pin <0){
digitalWrite(-pin,LOW);
}else{
digitalWrite(pin,HIGH);
}
//Serial.println('0');
}
}
void AnalogHandler(int mode, String data){
if(mode<=0){ //read
int pin = Str2int(data);
Serial.println(analogRead(pin));
}else{
String sdata[2];
split(sdata,2,data,'%');
int pin = Str2int(sdata[0]);
int pv = Str2int(sdata[1]);
analogWrite(pin,pv);
}
}
void ConfigurePinHandler(String data){
int pin = Str2int(data);
if(pin <=0){
pinMode(-pin,INPUT);
}else{
pinMode(pin,OUTPUT);
}
}
void shiftOutHandler(String data) {
String sdata[4];
split(sdata, 4, data, '%');
int dataPin = sdata[0].toInt();
int clockPin = sdata[1].toInt();
String bitOrderName = sdata[2];
byte value = (byte)(sdata[3].toInt());
if (bitOrderName == "MSBFIRST") {
shiftOut(dataPin, clockPin, MSBFIRST, value);
} else {
shiftOut(dataPin, clockPin, LSBFIRST, value);
}
}
void shiftInHandler(String data) {
String sdata[3];
split(sdata, 3, data, '%');
int dataPin = sdata[0].toInt();
int clockPin = sdata[1].toInt();
String bitOrderName = sdata[2];
int incoming;
if (bitOrderName == "MSBFIRST") {
incoming = (int)shiftIn(dataPin, clockPin, MSBFIRST);
} else {
incoming = (int)shiftIn(dataPin, clockPin, LSBFIRST);
}
Serial.println(incoming);
}
void SS_set(String data){
delete sserial;
String sdata[3];
split(sdata,3,data,'%');
int rx_ = Str2int(sdata[0]);
int tx_ = Str2int(sdata[1]);
int baud_ = Str2int(sdata[2]);
sserial = new SoftwareSerial(rx_, tx_);
sserial->begin(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();
}