-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SKARSTA: Adding functionality to control the table with serial communication #137
Conversation
Merge changes of serial communication with current commit
Great contibution thanks! After uploading my code to the D1 mini, I can see the controls appear in Home Assistant. I'm only stuggling with the pinout of both the D1 and the Arduino Nano. I have not changed anything on the code. Right now I tried to connect the TX/RX pins from the Arduino to the D0/D5 pins of the Wemos. The wemos is powered through the Nano's 3v and GND pins. |
Have you uploaded the code of this PR (link) to the nano? It is not yet merged into the master branch. |
Yup, I have checked the changes before uploading the code to the Nano. On the Home assistant end, I can read the Wemos output:
Commands I'm giving in the frontend are getting through but no reaction of the motor. For pinout, I have connected the TX of the Wemos to the RX of the nano and vice versa like you mentioned. Could I read any logs on the Nano to see if commands from the Wemos are getting through? edit; After looking at this log, it does seem that I would need to hook up TX/RX of the Nano to GPIO16 and 14 of the Wemos? I tried this, but that doesn't seem to work either.. edit2; I'm also abit confused about TX/RX being 11/12 by default. On pinout pictures of the Nano I see TX/RX being labeled as PD0 and PD1. But Arduino is a bit new to me as well, I'm sure I'm missing something obvious. edit3; Whenever I push a switch in HomeAssistant I see the red RX led lighting up on the Nano. TX stays off, also when I control the motor manually. |
That explains alot, thanks! All is working as intended. Really nifty future on the percentage scale in Home Assistant, makes automation even easier. I'm thinking of an automation that reminds you to stand up/sit down every now and then based on occupancy. |
Great! I'm glad you like it. :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! Could you summarize the setup procedure that is mentioned in this PR into skarsta/README.md
or skarsta/docs/
with examples? Also I'm curious about the use case with EspHome
do you have pre-scheduled times when the table moves?
It seems that some parts of code have inconsistent spacing, could you reformat it?
if (NULL != mySerial) { | ||
delete mySerial; | ||
} | ||
mySerial = new SoftwareSerial(ixPin, txPin); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be moved to to constructor like so?
SerialCom::SerialCom(Motor *motor, Calibrator *calibrator, uint8_t rx, uint8_t tx) :
motor(motor), calibrator(calibrator), mySerial(rx, tx) {
}
return true; | ||
} | ||
|
||
void SerialCom::disable() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be dropped
|
||
class SerialCom : public Service { | ||
private: | ||
bool disabled = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be dropped
|
||
#include <SoftwareSerial.h> | ||
|
||
const byte ixPin = 11; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ixPin
txPin
not used anywhere can be dropped
@@ -41,8 +42,9 @@ MotorRelay motor(SENSOR_PIN0, SENSOR_PIN1, POWER_RELAY, DIRECTION_RELAY, STOP_PO | |||
Display display(DISPLAY_PIN_CLK, DISPLAY_PIN_DIO, FADE_TIMEOUT); | |||
Watchdog watchdog(&motor, WATCHDOG_TIMEOUT, WATCHDOG_DEADLOCK_CHANGE, WATCHDOG_OTHER_CHANGE, WATCHDOG_OTHER_SLEEP); | |||
Calibrator calibrator(&motor); | |||
SerialCom serialCom(&motor, &calibrator, SERIAL_RX_PIN, SERIAL_TX_PIN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be optional feature enabled only via __ESPHOME__
{ | ||
float percent = min(100, max(0, line.toFloat())) / 100; | ||
int position = round(motor->get_end_stop_low() + (motor->get_end_stop_high() - motor->get_end_stop_low()) * percent); | ||
if (motor->get_mode() != CALIBRATED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check can be dropped as its redundant with
void Motor::set_position(unsigned int pos) {
if (mode != CALIBRATED || position_abs(pos, get_position()) < min_change) {
return;
}
set_motor(position);
can be simplified to
motor->set_position(position);
} | ||
|
||
void SerialCom::goto_preset(unsigned int preset) { | ||
if (motor->get_mode() != CALIBRATED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check can be dropped as its redundant with
void Motor::set_position(unsigned int pos) {
if (mode != CALIBRATED || position_abs(pos, get_position()) < min_change) {
return;
}
case 3: | ||
{ | ||
unsigned int preset = calibrator->get_preset(number - 1); | ||
goto_preset(preset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be simplified
motor->set_position(calibrator->get_preset(number - 1));
private: | ||
bool disabled = false; | ||
unsigned int pos_watch = 0; | ||
unsigned long last_update = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be replaced with TimedService
see Watchdog.cpp
for example
@@ -94,6 +94,10 @@ class Motor : public TimedService { | |||
|
|||
MotorMode get_mode() const; | |||
|
|||
unsigned int get_end_stop_low(); | |||
unsigned int get_end_stop_high(); | |||
long get_next_position(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be dropped as not needed
I created a new Service called
SerialCom
that adds the functionality to control the table with serial communication.It also sends the current position of the table (in a special format [see below]) to the serial connection every time it changes, but at a maximum rate of every 500ms.
The
SERIAL_TX_PIN
andSERIAL_RX_PIN
pins can be changed in the configuration.h file (default RX = 12; default TX = 11)The baud rate of the serial connection is 9600.
Serial Input
Every command to the table has to be a new line. So in my case I add
\r\n
to every command string I send to the table.The first character of the command signals the type of command.
It accepts the following commands:
%75
)This sets the table position to <number> percent. The value is cramped between 0 and 100. The number can be a float.
#2
)Move the table to the <number> preset. Accepted integers are 1, 2 and 3.
This requests the service to send the current table position over the serial connection without changing it.
This stops the motor.
This starts the motor to spin cw until stopped.
This starts the motor to spin ccw until stopped.
Serial Output
The output to the serial connection of the table is always the current position. It will send every time the table position changes but twice per second at most.
It sends it in the following format:
<number1>/<number2> (e.g.
782/2187
). <number1> is the current position and <number2> is the maximum range of the table (end_stop[0] - end_stop[1]).My Use Case
I use this serial communication to control my table with a
Wemos D1 mini
chip over WiFi. This chip uses ESPHome and is integrated in my personal Home Assistant installation.My skarsta.yaml config looks like follows:
The UartReadLineSensor I use in my skarsta.yaml is in a file called uart_read_line_sensor.h in my esphome directory and has the follwin contents: