Compare commits
7 Commits
744d30ef76
...
5a82d0d988
Author | SHA1 | Date |
---|---|---|
BodgeMaster | 5a82d0d988 | |
BodgeMaster | 0d77f15de5 | |
BodgeMaster | 9cc0955003 | |
BodgeMaster | 221e01033e | |
BodgeMaster | da29965b64 | |
BodgeMaster | f896e72ef6 | |
BodgeMaster | a9d3f5273c |
|
@ -13,3 +13,9 @@ Dependencies: Linux kernel, bash, sysfs filesystem mounted on /sys
|
||||||
Can be used to get the state of a hardware sensor connected to the computer.
|
Can be used to get the state of a hardware sensor connected to the computer.
|
||||||
|
|
||||||
Dependencies: lm-sensors, python3
|
Dependencies: lm-sensors, python3
|
||||||
|
|
||||||
|
### [manual_control](./manual_control/manual_control.ino)
|
||||||
|
Arduino sketch that allows direct manual control of the pins over the serial interface. This is the older, fancier version which is only capable of controlling outputs. It has some hardcoded values that may need to be adjusted.
|
||||||
|
|
||||||
|
### [external_control](./external_control/external_control.ino)
|
||||||
|
A less fancy but generally improved rewritten version of the manual control Arduino sketch that is more feature-packed and better suited for interaction with programs while still being usable for humans.
|
||||||
|
|
|
@ -0,0 +1,260 @@
|
||||||
|
/*
|
||||||
|
* getMode function has been taken from https://forum.arduino.cc/t/check-current-pinmode/232140
|
||||||
|
*/
|
||||||
|
#define UNKNOWN_PIN 0xFF
|
||||||
|
#define TX_PIN 1
|
||||||
|
#define RX_PIN 0
|
||||||
|
|
||||||
|
uint8_t getMode(uint8_t pin){
|
||||||
|
uint8_t bitmask = digitalPinToBitMask(pin);
|
||||||
|
uint8_t port = digitalPinToPort(pin);
|
||||||
|
|
||||||
|
// I don't see an option for mega to return this, but whatever...
|
||||||
|
if (port == NOT_A_PIN) return UNKNOWN_PIN;
|
||||||
|
|
||||||
|
// Is there a bit we can check?
|
||||||
|
if (bitmask == 0) return UNKNOWN_PIN;
|
||||||
|
|
||||||
|
// Is there only a single bit set?
|
||||||
|
if (bitmask & bitmask - 1) return UNKNOWN_PIN;
|
||||||
|
|
||||||
|
volatile uint8_t *reg, *out;
|
||||||
|
reg = portModeRegister(port);
|
||||||
|
out = portOutputRegister(port);
|
||||||
|
|
||||||
|
if (*reg & bitmask)
|
||||||
|
return OUTPUT;
|
||||||
|
else if (*out & bitmask)
|
||||||
|
return INPUT_PULLUP;
|
||||||
|
else
|
||||||
|
return INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t toggleState(uint8_t pin){
|
||||||
|
uint8_t mode = getMode(pin);
|
||||||
|
switch (mode) {
|
||||||
|
case OUTPUT:
|
||||||
|
if (digitalRead(pin) == HIGH) {
|
||||||
|
digitalWrite(pin, LOW);
|
||||||
|
return LOW;
|
||||||
|
} else {
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
return HIGH;
|
||||||
|
}
|
||||||
|
case INPUT_PULLUP:
|
||||||
|
pinMode(pin, INPUT);
|
||||||
|
return LOW;
|
||||||
|
case INPUT:
|
||||||
|
pinMode(pin, INPUT_PULLUP);
|
||||||
|
return HIGH;
|
||||||
|
default:
|
||||||
|
return UNKNOWN_PIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t toggleMode(uint8_t pin){
|
||||||
|
uint8_t mode = getMode(pin);
|
||||||
|
// declared here bc it won’t let me inside the switch/case statement
|
||||||
|
uint8_t state;
|
||||||
|
switch (mode) {
|
||||||
|
case OUTPUT:
|
||||||
|
state = digitalRead(pin);
|
||||||
|
pinMode(pin, INPUT);
|
||||||
|
digitalWrite(pin, state);
|
||||||
|
return getMode(pin); // probably sacrificed performance for readability here
|
||||||
|
case INPUT_PULLUP:
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
return OUTPUT;
|
||||||
|
case INPUT:
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
digitalWrite(pin, LOW);
|
||||||
|
return OUTPUT;
|
||||||
|
default:
|
||||||
|
return UNKNOWN_PIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
String waitForSerialInput(uint8_t bytes){
|
||||||
|
uint8_t inputLength = 0;
|
||||||
|
String string = "";
|
||||||
|
uint8_t waitingCycles = 0;
|
||||||
|
while (inputLength < bytes) {
|
||||||
|
if (Serial.available() > 0) {
|
||||||
|
string = string + (char)Serial.read();
|
||||||
|
inputLength = inputLength+1;
|
||||||
|
waitingCycles = 0;
|
||||||
|
} else {
|
||||||
|
if (waitingCycles > 100) {
|
||||||
|
Serial.print(".");
|
||||||
|
delay(500);
|
||||||
|
waitingCycles = 0;
|
||||||
|
} else {
|
||||||
|
waitingCycles = waitingCycles+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void runCommand(){
|
||||||
|
uint8_t command = Serial.read();
|
||||||
|
int analogPin;
|
||||||
|
String mode;
|
||||||
|
uint8_t pin;
|
||||||
|
String state;
|
||||||
|
switch ((char)command) {
|
||||||
|
case 'R': // run setup() again
|
||||||
|
Serial.print("R");
|
||||||
|
Serial.end();
|
||||||
|
setup();
|
||||||
|
return;
|
||||||
|
case 'h': // print help information
|
||||||
|
Serial.print("h");
|
||||||
|
Serial.print(F("\n\r"
|
||||||
|
"status (output from serial line)\n\r"
|
||||||
|
" <letter of command> command acknowledgement\n\r"
|
||||||
|
" . internal operation or waiting for input\n\r"
|
||||||
|
" <data>\n\r"
|
||||||
|
" s success\n\r"
|
||||||
|
" e error\n\r"
|
||||||
|
" \\r\\n ready (this message uses \n\r to not show up as \"ready\" after the first line)\n\r"
|
||||||
|
"commands (input to serial line)\n\r"
|
||||||
|
" R pseudo-reset\n\r"
|
||||||
|
" run setup again\n\r"
|
||||||
|
" h show help\n\r"
|
||||||
|
" m set mode\n\r"
|
||||||
|
" usage: followed by two digit pin number and o or i\n\r"
|
||||||
|
" set a pin to input or output mode\n\r"
|
||||||
|
" \"pinMode\"\n\r"
|
||||||
|
" x toggle mode\n\r"
|
||||||
|
" usage: followed by two digit pin number\n\r"
|
||||||
|
" toggle a pin's mode\n\r"
|
||||||
|
" enables pullup resistor for previously high output pins\n\r"
|
||||||
|
" sets output high for previous input pins with pullup enabled\n\r"
|
||||||
|
" a analog read\n\r"
|
||||||
|
" usage: followed by two digit analog pin number\n\r"
|
||||||
|
" returns state of an analog pin\n\r"
|
||||||
|
" pin number will be converted to digital pin automatically\n\r"
|
||||||
|
" r read\n\r"
|
||||||
|
" usage: followed by pin number\n\r"
|
||||||
|
" returns state of a pin\n\r"
|
||||||
|
" \"digitalRead\"\n\r"
|
||||||
|
" w write\n\r"
|
||||||
|
" usage: followed by two digit pin number and h or l\n\r"
|
||||||
|
" sets a pin to the desired state\n\r"
|
||||||
|
" sets pullup resistor for input pins\n\r"
|
||||||
|
" \"digitalWrite\"\n\r"
|
||||||
|
" p write pwm\n\r"
|
||||||
|
" usage: followed by two digit pin number and three digit value between 000 and 255\n\r"
|
||||||
|
" \"analogWrite\"\n\r"
|
||||||
|
" t toggle pin state\n\r"
|
||||||
|
" usage: followed by two digit pin number\n\r"
|
||||||
|
" toggles state of output pins\n\r"
|
||||||
|
" toggles pullup resistor for input pins\n\r"
|
||||||
|
" l change led state\n\r"
|
||||||
|
" usage: followed by h (high), l (low) or t (toggle)\n\r"
|
||||||
|
" sets or toggles the state of LED_BUILTIN\n\r"
|
||||||
|
" q lock\n\r"
|
||||||
|
" lock the Arduino's state by running an infinite loop\n\r"
|
||||||
|
"\n\rs"));
|
||||||
|
return;
|
||||||
|
case 'm': // set pin mode
|
||||||
|
Serial.print("m");
|
||||||
|
pin = waitForSerialInput(2).toInt();
|
||||||
|
mode = waitForSerialInput(1);
|
||||||
|
if (pin >= NUM_DIGITAL_PINS) Serial.print("e");
|
||||||
|
else if (mode=="i") {
|
||||||
|
pinMode(pin, INPUT);
|
||||||
|
Serial.print("s");
|
||||||
|
} else if (mode=="o") {
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
Serial.print("s");
|
||||||
|
} else {
|
||||||
|
Serial.print("e");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case 'x': // toggle pin mode
|
||||||
|
Serial.print("x");
|
||||||
|
if (toggleMode((uint8_t)waitForSerialInput(2).toInt()) == UNKNOWN_PIN) Serial.print("e");
|
||||||
|
else Serial.print("s");
|
||||||
|
return;
|
||||||
|
case 'a': // read analog pin
|
||||||
|
Serial.print("a");
|
||||||
|
analogPin = waitForSerialInput(2).toInt();
|
||||||
|
if (analogPin>=NUM_ANALOG_INPUTS || analogInputToDigitalPin(analogPin)<0){
|
||||||
|
Serial.print("e");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.print(analogRead(analogInputToDigitalPin(analogPin)));
|
||||||
|
Serial.print("s");
|
||||||
|
return;
|
||||||
|
case 'r': // read digital value
|
||||||
|
/*bug:
|
||||||
|
The following "r" (or any other text you may put there) will never get printed despite this code branch being executed. Don’t ask me why or how.
|
||||||
|
Tested on Linux Mint 20.1, Arduino IDE version 2:1.0.5+dfsg2-4.1
|
||||||
|
Tested with Arduino Uno and Nano 328P
|
||||||
|
*/
|
||||||
|
Serial.print("r");
|
||||||
|
pin = waitForSerialInput(2).toInt();
|
||||||
|
if (pin >= NUM_DIGITAL_PINS) Serial.print("e");
|
||||||
|
else {
|
||||||
|
Serial.print(digitalRead(pin));
|
||||||
|
Serial.print("s");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case 'w': // write digital pin
|
||||||
|
Serial.print("w");
|
||||||
|
pin = waitForSerialInput(2).toInt();
|
||||||
|
state = waitForSerialInput(1);
|
||||||
|
if (pin >= NUM_DIGITAL_PINS) Serial.print("e");
|
||||||
|
else if (state == "h") {
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
Serial.print("s");
|
||||||
|
} else if (state == "l") {
|
||||||
|
digitalWrite(pin, LOW);
|
||||||
|
Serial.print("s");
|
||||||
|
} else {
|
||||||
|
Serial.print("e");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
Serial.print("e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(230400);
|
||||||
|
// set all pins to input and low
|
||||||
|
for (uint8_t i; i<=NUM_DIGITAL_PINS; i++) {
|
||||||
|
Serial.print(".");
|
||||||
|
if (i==TX_PIN || i==RX_PIN);
|
||||||
|
else pinMode(i, INPUT);
|
||||||
|
}
|
||||||
|
Serial.print(".");
|
||||||
|
pinMode(LED_BUILTIN, OUTPUT); // set LED to output bc having it as an input would make little sense
|
||||||
|
while (Serial.available() > 0) {
|
||||||
|
Serial.print(".");
|
||||||
|
Serial.read();
|
||||||
|
}
|
||||||
|
Serial.print("s\r\n");
|
||||||
|
// testing
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
while (true){
|
||||||
|
if(Serial.available() > 0) {
|
||||||
|
runCommand();
|
||||||
|
Serial.print("\r\n"); // send "ready" status information
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,7 +41,6 @@ void setup() { //initial setup and reset
|
||||||
pins[i]=LOW;
|
pins[i]=LOW;
|
||||||
} // setup serial connection
|
} // setup serial connection
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
delay(100); //Printing the welcome message immediately ... may cause issues.
|
|
||||||
Serial.print(color_null+"-=[ Arduino Serial Manual Pin Control ]=-\n\r");
|
Serial.print(color_null+"-=[ Arduino Serial Manual Pin Control ]=-\n\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue