mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-26 15:54:29 +02:00
Added task for reading serial
Added task for reading serial
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
Part of Grbl
|
Part of Grbl
|
||||||
Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
|
Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||||
|
|
||||||
2018 - Bart Dring This file was modifed for use on the ESP32
|
2018 - Bart Dring This file was modified for use on the ESP32
|
||||||
CPU. Do not use this with Grbl for atMega328P
|
CPU. Do not use this with Grbl for atMega328P
|
||||||
|
|
||||||
Grbl is free software: you can redistribute it and/or modify
|
Grbl is free software: you can redistribute it and/or modify
|
||||||
@@ -27,58 +27,6 @@ uint8_t serial_rx_buffer[RX_RING_BUFFER];
|
|||||||
uint8_t serial_rx_buffer_head = 0;
|
uint8_t serial_rx_buffer_head = 0;
|
||||||
volatile uint8_t serial_rx_buffer_tail = 0;
|
volatile uint8_t serial_rx_buffer_tail = 0;
|
||||||
|
|
||||||
//ISR(SERIAL_RX)
|
|
||||||
uint8_t check_action_command(uint8_t data)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Pick off realtime command characters directly from the serial stream. These characters are
|
|
||||||
// not passed into the main buffer, but these set system state flag bits for realtime execution.
|
|
||||||
switch (data) {
|
|
||||||
case CMD_RESET: mc_reset(); break; // Call motion control reset routine.
|
|
||||||
case CMD_STATUS_REPORT: system_set_exec_state_flag(EXEC_STATUS_REPORT); break; // Set as true
|
|
||||||
case CMD_CYCLE_START: system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true
|
|
||||||
case CMD_FEED_HOLD: system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true
|
|
||||||
default :
|
|
||||||
if (data > 0x7F) { // Real-time control characters are extended ACSII only.
|
|
||||||
switch(data) {
|
|
||||||
case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true
|
|
||||||
case CMD_JOG_CANCEL:
|
|
||||||
if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel.
|
|
||||||
system_set_exec_state_flag(EXEC_MOTION_CANCEL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#ifdef DEBUG
|
|
||||||
case CMD_DEBUG_REPORT: {uint8_t sreg = SREG; cli(); bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); SREG = sreg;} break;
|
|
||||||
#endif
|
|
||||||
case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break;
|
|
||||||
case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break;
|
|
||||||
case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break;
|
|
||||||
case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break;
|
|
||||||
case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break;
|
|
||||||
case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break;
|
|
||||||
case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break;
|
|
||||||
case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break;
|
|
||||||
case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break;
|
|
||||||
case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break;
|
|
||||||
case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break;
|
|
||||||
case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break;
|
|
||||||
case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break;
|
|
||||||
case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break;
|
|
||||||
case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break;
|
|
||||||
#ifdef ENABLE_M7
|
|
||||||
case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// Throw away any unfound extended-ASCII character by not passing it to the serial buffer.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the number of bytes available in the RX serial buffer.
|
// Returns the number of bytes available in the RX serial buffer.
|
||||||
uint8_t serial_get_rx_buffer_available()
|
uint8_t serial_get_rx_buffer_available()
|
||||||
@@ -91,6 +39,87 @@ uint8_t serial_get_rx_buffer_available()
|
|||||||
void serial_init()
|
void serial_init()
|
||||||
{
|
{
|
||||||
Serial.begin(BAUD_RATE);
|
Serial.begin(BAUD_RATE);
|
||||||
|
|
||||||
|
// create a task to check for incoming data
|
||||||
|
xTaskCreatePinnedToCore( serialCheckTask, // task
|
||||||
|
"servoSyncTask", // name for task
|
||||||
|
2048, // size of task stack
|
||||||
|
NULL, // parameters
|
||||||
|
1, // priority
|
||||||
|
&serialCheckTaskHandle,
|
||||||
|
0 // core
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// this task runs and checks for data on all interfaces, currently
|
||||||
|
// only hardware serial port is checked
|
||||||
|
// This was normally done in an interrupt on 8-bit Grbl
|
||||||
|
void serialCheckTask(void *pvParameters)
|
||||||
|
{
|
||||||
|
uint8_t data;
|
||||||
|
uint8_t next_head;
|
||||||
|
|
||||||
|
while(true) // run continuously
|
||||||
|
{
|
||||||
|
while (Serial.available()) // loop until all characters are read
|
||||||
|
{
|
||||||
|
data = Serial.read();
|
||||||
|
|
||||||
|
// Pick off realtime command characters directly from the serial stream. These characters are
|
||||||
|
// not passed into the main buffer, but these set system state flag bits for realtime execution.
|
||||||
|
switch (data) {
|
||||||
|
case CMD_RESET: mc_reset(); break; // Call motion control reset routine.
|
||||||
|
case CMD_STATUS_REPORT: system_set_exec_state_flag(EXEC_STATUS_REPORT); break; // Set as true
|
||||||
|
case CMD_CYCLE_START: system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true
|
||||||
|
case CMD_FEED_HOLD: system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true
|
||||||
|
default :
|
||||||
|
if (data > 0x7F) { // Real-time control characters are extended ACSII only.
|
||||||
|
switch(data) {
|
||||||
|
case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true
|
||||||
|
case CMD_JOG_CANCEL:
|
||||||
|
if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel.
|
||||||
|
system_set_exec_state_flag(EXEC_MOTION_CANCEL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef DEBUG
|
||||||
|
case CMD_DEBUG_REPORT: {uint8_t sreg = SREG; cli(); bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); SREG = sreg;} break;
|
||||||
|
#endif
|
||||||
|
case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break;
|
||||||
|
case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break;
|
||||||
|
case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break;
|
||||||
|
case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break;
|
||||||
|
case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break;
|
||||||
|
case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break;
|
||||||
|
case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break;
|
||||||
|
case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break;
|
||||||
|
case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break;
|
||||||
|
case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break;
|
||||||
|
case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break;
|
||||||
|
case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break;
|
||||||
|
case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break;
|
||||||
|
case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break;
|
||||||
|
case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break;
|
||||||
|
#ifdef ENABLE_M7
|
||||||
|
case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// Throw away any unfound extended-ASCII character by not passing it to the serial buffer.
|
||||||
|
} else { // Write character to buffer
|
||||||
|
next_head = serial_rx_buffer_head + 1;
|
||||||
|
if (next_head == RX_RING_BUFFER) { next_head = 0; }
|
||||||
|
|
||||||
|
// Write data to buffer unless it is full.
|
||||||
|
if (next_head != serial_rx_buffer_tail) {
|
||||||
|
serial_rx_buffer[serial_rx_buffer_head] = data;
|
||||||
|
serial_rx_buffer_head = next_head;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // switch data
|
||||||
|
|
||||||
|
} // if data
|
||||||
|
vTaskDelay(1 / portTICK_RATE_MS); // Yield to other tasks
|
||||||
|
} // while
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_reset_read_buffer()
|
void serial_reset_read_buffer()
|
||||||
@@ -102,28 +131,21 @@ void serial_reset_read_buffer()
|
|||||||
void serial_write(uint8_t data) {
|
void serial_write(uint8_t data) {
|
||||||
Serial.write((char)data);
|
Serial.write((char)data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches the first byte in the serial read buffer. Called by main program.
|
// Fetches the first byte in the serial read buffer. Called by main program.
|
||||||
uint8_t serial_read()
|
uint8_t serial_read()
|
||||||
{
|
{
|
||||||
uint8_t c;
|
uint8_t tail = serial_rx_buffer_tail; // Temporary serial_rx_buffer_tail (to optimize for volatile)
|
||||||
|
if (serial_rx_buffer_head == tail) {
|
||||||
if (Serial.available())
|
return SERIAL_NO_DATA;
|
||||||
{
|
} else {
|
||||||
c = Serial.read();
|
uint8_t data = serial_rx_buffer[tail];
|
||||||
if (check_action_command(c))
|
|
||||||
{
|
tail++;
|
||||||
// it got processed so throw it away
|
if (tail == RX_RING_BUFFER) { tail = 0; }
|
||||||
return SERIAL_NO_DATA;
|
serial_rx_buffer_tail = tail;
|
||||||
}
|
|
||||||
else
|
return data;
|
||||||
{
|
}
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return SERIAL_NO_DATA;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -36,6 +36,10 @@
|
|||||||
|
|
||||||
#define SERIAL_NO_DATA 0xff
|
#define SERIAL_NO_DATA 0xff
|
||||||
|
|
||||||
|
// a task to read for incoming data from serial port
|
||||||
|
static TaskHandle_t serialCheckTaskHandle = 0;
|
||||||
|
void serialCheckTask(void *pvParameters);
|
||||||
|
|
||||||
void serial_write(uint8_t data);
|
void serial_write(uint8_t data);
|
||||||
// Fetches the first byte in the serial read buffer. Called by main program.
|
// Fetches the first byte in the serial read buffer. Called by main program.
|
||||||
uint8_t serial_read();
|
uint8_t serial_read();
|
||||||
|
13
README.md
13
README.md
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Status: Functional Beta (See issues below)
|
### Status: Functional Beta (See minor issues below)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -22,9 +22,8 @@ This is a port of [Grbl](https://github.com/gnea/grbl) for the ESP32. The ESP32
|
|||||||
|
|
||||||
### Issues / Changes
|
### Issues / Changes
|
||||||
|
|
||||||
1. **Startup Text** - Can we get rid of the ESP32 startup text? It might annoy some senders. It is probably possible using sdkconfig.h. but that might be difficult for the novice Arduino IDE user.
|
1. **Direction pin delay** - Not implemented yet. Some drivers require a couple of microseconds after the direction pin is set before you start the step pulse. The original plan was to [use the RMT feature](http://www.buildlog.net/blog/?s=rmt), but that has issues when trying to use it in an Interrupt.
|
||||||
2. **Direction pin delay** - Not implemented yet. Some drivers require a couple of microseconds after the direction pin is set before you start the step pulse. The original plan was to [use the RMT feature](http://www.buildlog.net/blog/?s=rmt), but that has issues when trying to use it in an Interrupt.
|
2. **Limit Switch debouncing** is not supported yet. It does not seem to be a problem on my test rigs. It might be better to us an R/C filter for now.
|
||||||
3. **Limit Switch debouncing** is not supported yet. It does not seem to be a problem on my test rigs. It might be better to us an R/C filter for now.
|
|
||||||
|
|
||||||
### Using It
|
### Using It
|
||||||
|
|
||||||
@@ -34,11 +33,13 @@ I use the NodeMCU 32S version of the ESP32. I suggest starting with that if you
|
|||||||
|
|
||||||
For basic instructions on using Grbl use the [gnea/grbl wiki](https://github.com/gnea/grbl/wiki). That is the Arduino version of Grbl, so keep that in mind regarding hardware setup. If you have questions ask via the GitHub issue system for this project.
|
For basic instructions on using Grbl use the [gnea/grbl wiki](https://github.com/gnea/grbl/wiki). That is the Arduino version of Grbl, so keep that in mind regarding hardware setup. If you have questions ask via the GitHub issue system for this project.
|
||||||
|
|
||||||
|
Note: Unlike Grbl on Arduinos, the controller does not reboot when you connect to it via USB.
|
||||||
|
|
||||||
### TODO List
|
### TODO List
|
||||||
|
|
||||||
- RMT. The RMT feature is a ideal for direction and step features, but apparently has issues working in interrupts. See [this forum post](https://www.esp32.com/viewtopic.php?f=19&t=6397&hilit=grbl) and [this blog post](http://www.buildlog.net/blog/?s=rmt). It would be great to get it working.
|
- RMT. The RMT feature is a ideal for direction and step features, but apparently has issues working in interrupts. See [this forum post](https://www.esp32.com/viewtopic.php?f=19&t=6397&hilit=grbl) and [this blog post](http://www.buildlog.net/blog/?s=rmt). It would be great to get it working.
|
||||||
- Add spindle enable and direction.
|
- Add spindle enable and direction.
|
||||||
- Bluetooth - Add it so phones and PCs can use it to stream gcode. It would be great if it looks like a bluetooth serial port, that helps with compatibility with existing apps. ([Android Grbl Controller](https://play.google.com/store/apps/details?id=in.co.gorest.grblcontroller&hl=en_US) is best!)
|
- [Bluetooth](https://github.com/bdring/Grbl_Esp32/issues/3) - Add it so phones and PCs can use it to stream gcode. It would be great if it looks like a bluetooth serial port, that helps with compatibility with existing apps. ([Android Grbl Controller](https://play.google.com/store/apps/details?id=in.co.gorest.grblcontroller&hl=en_US) is best!)
|
||||||
|
|
||||||
### Credits
|
### Credits
|
||||||
|
|
||||||
@@ -48,6 +49,8 @@ The original [Grbl](https://github.com/gnea/grbl) is an awesome project by Sunge
|
|||||||
|
|
||||||
I would love to have help with this project. There are many things that need to be improved and added, especially BlueTooth and/or WiFi. If you need hardware to test with, I might be able to help with a test PCB.
|
I would love to have help with this project. There are many things that need to be improved and added, especially BlueTooth and/or WiFi. If you need hardware to test with, I might be able to help with a test PCB.
|
||||||
|
|
||||||
|
 [Slack channel](https://join.slack.com/t/buildlog/shared_invite/enQtNDA1ODM5MzI3MjE2LWYxNzMwZmNmMWVhYmUzMDdiYWQxMjk2MWQ1NzJhYzc2Mjg5NmRjMWI2MmM3OGE4M2JiZWQ2MThjMjQ3Y2U2OTE) for this project.
|
||||||
|
|
||||||
### FAQ
|
### FAQ
|
||||||
|
|
||||||
Start asking questions...I'll put the frequent ones here.
|
Start asking questions...I'll put the frequent ones here.
|
||||||
|
Reference in New Issue
Block a user