fix serial receiving

This commit is contained in:
Paul Dino Jones 2025-07-14 00:15:47 -04:00
parent f6a2607273
commit d2fa72f47c
4 changed files with 294 additions and 122 deletions

View File

@ -42,63 +42,111 @@ int arduino_update(SerialDevice* serialdevice, void* data, size_t size)
return result;
}
// the input event waiting and flushing is the right way to do this
// most of the time i'm just "bit blasting" and the only receiving
// happens initially to get the number of lights
int GetNumberOfLeds(SerialDevice* serialdevice, int* numlights)
{
int count = 0;
int bytesWaiting;
char buf[256];
int retval = 0;
int i;
//sp_flush(port, SP_BUF_INPUT);
while (count < 4)
{
slogi("Attempting to retrieve num lights from port...");
size_t bufsize1 = 11;
size_t recv_bufsize1 = 5;
char recv_buf1[recv_bufsize1];
char bytes1[bufsize1];
for(int j = 0; j < bufsize1; j++)
{
bytes1[j] = 0x00;
}
bytes1[0] = 0xff;
bytes1[1] = 0xff;
bytes1[2] = 0xff;
bytes1[3] = 0xff;
bytes1[4] = 0xff;
bytes1[5] = 0xff;
bytes1[6] = 0x6c;
bytes1[7] = 0x65;
bytes1[8] = 0x64;
bytes1[9] = 0x73;
bytes1[10] = 0x63;
int result = 0;
unsigned int timeout = 6000;
slogd("Sending message to get num lights");
monocoque_wait_for_event(serialdevice->id, 6);
result = monocoque_serial_write(serialdevice->id, &bytes1, bufsize1, arduino_timeout);
monocoque_wait_for_event(serialdevice->id, 5);
bytesWaiting = monocoque_input_wait(serialdevice->id);
if (bytesWaiting > 0)
{
memset(buf, 0, sizeof(buf));
retval = monocoque_serial_read_block(serialdevice->id, buf, sizeof(buf)-1, 10);
if (retval < 0)
{
retval = -1;
break;
}
else
{
for(i=0; i<retval; i++)
{
if (buf[i] == 13)
{
count++;
}
}
int ret = atoi(buf);
*numlights = ret;
return retval;
}
}
else
if (bytesWaiting < 0)
{
sloge("Error getting bytes available from serial port: %d", bytesWaiting);
retval = -1;
break;
}
retval = 0;
}
return retval;
}
int arduino_init(SerialDevice* serialdevice, const char* portdev)
{
serialdevice->id = monocoque_serial_open(serialdevice, portdev);
return serialdevice->id;
}
int arduino_customled_init(SerialDevice* serialdevice, const char* portdev, const char* luafile)
{
serialdevice->id = monocoque_serial_open(serialdevice, portdev);
size_t bufsize1 = 11;
size_t recv_bufsize1 = 5;
char recv_buf1[recv_bufsize1];
char bytes1[bufsize1];
for(int j = 0; j < bufsize1; j++)
{
bytes1[j] = 0x00;
}
bytes1[0] = 0xff;
bytes1[1] = 0xff;
bytes1[2] = 0xff;
bytes1[3] = 0xff;
bytes1[4] = 0xff;
bytes1[5] = 0xff;
bytes1[6] = 0x6c;
bytes1[7] = 0x65;
bytes1[8] = 0x64;
bytes1[9] = 0x73;
bytes1[10] = 0x63;
int numlights = 0;
int result = 0;
unsigned int timeout = 3000;
result = monocoque_serial_write_block(serialdevice->id, &bytes1, bufsize1, timeout);
result = monocoque_serial_read_block(serialdevice->id, &recv_buf1, recv_bufsize1, timeout);
//slogi("wrote %i bytes", result);
//sleep(2);
//monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevice->id];
//result = arduino_check(sp_blocking_read(monocoque_serial_dev.port, &recv_buf1, recv_bufsize1, 5000));
//slogi("read %i bytes", result);
//result = sp_blocking_read(serialdevice->port, &recv_buf1, recv_bufsize1, timeout);
monocoque_serial_device serialdev = monocoque_serial_devices[serialdevice->id];
int error = GetNumberOfLeds(serialdevice, &numlights);
char numstr[recv_bufsize1];
for(int j = 0; j < recv_bufsize1; j++)
{
numstr[j] = '\0';
}
for(int j = 0; j < recv_bufsize1; j++)
{
if(recv_buf1[j] != 0 && recv_buf1[j] != 0x0d && recv_buf1[j] != 0x0a)
{
numstr[j] = recv_buf1[j];
}
}
int numlights = atoi(numstr);
serialdevice->numleds = numlights;
slogi("numlights is %i\n", numlights);
// close, error and free if numlights is 0
serialdevice->numleds = numlights;
if(luafile == NULL)
{

View File

@ -73,6 +73,47 @@ int monocoque_serial_free(SerialDevice* serialdevice)
}
}
int monocoque_wait_for_event(uint8_t serialdevicenum, int event)
{
slogt("serial device id %i", serialdevicenum);
monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevicenum];
int retval;
struct sp_event_set* eventSet = NULL;
retval = sp_new_event_set(&eventSet);
if (retval == SP_OK)
{
retval = sp_add_port_events(eventSet, monocoque_serial_dev.port, event);
if (retval == SP_OK)
{
slogd("set event on port");
retval = sp_wait(eventSet, 5000);
}
else
{
sloge("Unable to add events to port.");
retval = -1;
}
}
else
{
sloge("Unable to create new event set.");
retval = -1;
}
sp_free_event_set(eventSet);
return retval;
}
int monocoque_input_wait(uint8_t serialdevicenum)
{
monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevicenum];
return sp_input_waiting(monocoque_serial_dev.port);
}
int monocoque_serial_write(uint8_t serialdevicenum, void* data, size_t size, int timeout)
{
slogt("serial device id %i", serialdevicenum);
@ -216,7 +257,7 @@ int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev)
}
slogd("Opening port");
check(sp_open(sp, SP_MODE_READ_WRITE));
check(sp_open(sp, SP_MODE_READ | SP_MODE_WRITE));
slogd("Setting port to %i 8N1, no flow control", serialdevice->baudrate);
check(sp_set_baudrate(sp, serialdevice->baudrate));
@ -225,6 +266,9 @@ int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev)
check(sp_set_stopbits(sp, 1));
check(sp_set_flowcontrol(sp, SP_FLOWCONTROL_NONE));
check(sp_set_rts(sp, 1));
check(sp_set_dtr(sp, 1));
monocoque_serial_devices[i].port = sp;
monocoque_serial_devices[i].open = true;

View File

@ -20,6 +20,8 @@ monocoque_serial_device;
static monocoque_serial_device monocoque_serial_devices[20];
int monocoque_input_wait(uint8_t serialdevicenum);
int monocoque_wait_for_event(uint8_t serialdevicenum, int event);
int monocoque_serial_write(uint8_t serialdevicenum, void* data, size_t size, int timeout);
int monocoque_serial_write_block(uint8_t serialdevicenum, void* data, size_t size, int timeout);
int monocoque_serial_read_block(uint8_t serialdevicenum, void* data, size_t size, int timeout);

View File

@ -1,16 +1,163 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <libserialport.h>
#include "../src/arduino/shiftlights/shiftlights.h"
/* Helper function for error handling. */
int check(enum sp_return result);
int check(enum sp_return result)
{
/* For this example we'll just exit on any error by calling abort(). */
char* error_message;
switch (result)
{
case SP_ERR_ARG:
printf("Error: Invalid argument.\n");
abort();
case SP_ERR_FAIL:
error_message = sp_last_error_message();
printf("Error: Failed: %s\n", error_message);
sp_free_error_message(error_message);
abort();
case SP_ERR_SUPP:
printf("Error: Not supported.\n");
abort();
case SP_ERR_MEM:
printf("Error: Couldn't allocate memory.\n");
abort();
case SP_OK:
default:
return result;
}
}
int WaitForEventOnPort(struct sp_port* port, int event)
{
int retval;
struct sp_event_set* eventSet = NULL;
retval = sp_new_event_set(&eventSet);
if (retval == SP_OK)
{
retval = sp_add_port_events(eventSet, port, event);
if (retval == SP_OK)
{
printf("set event on port\n");
retval = sp_wait(eventSet, 5000);
}
else
{
puts("Unable to add events to port.");
retval = -1;
}
}
else
{
puts("Unable to create new event set.");
retval = -1;
}
sp_free_event_set(eventSet);
return retval;
}
// the input event waiting and flushing is the right way to do this
// most of the time i'm just "bit blasting" and the only receiving
// happens initially to get the number of lights
int ReadFromPort(struct sp_port* port, int* numlights)
{
int count = 0;
int bytesWaiting;
char buf[256];
int retval = 0;
int i;
sp_flush(port, SP_BUF_INPUT);
while (count < 4)
{
printf("Attempting to retrieve num lights from port...\n");
size_t bufsize1 = 11;
size_t recv_bufsize1 = 5;
char recv_buf1[recv_bufsize1];
char bytes1[bufsize1];
for(int j = 0; j < bufsize1; j++)
{
bytes1[j] = 0x00;
}
bytes1[0] = 0xff;
bytes1[1] = 0xff;
bytes1[2] = 0xff;
bytes1[3] = 0xff;
bytes1[4] = 0xff;
bytes1[5] = 0xff;
bytes1[6] = 0x6c;
bytes1[7] = 0x65;
bytes1[8] = 0x64;
bytes1[9] = 0x73;
bytes1[10] = 0x63;
int result = 0;
unsigned int timeout = 6000;
printf("Sending message to get num lights\n");
WaitForEventOnPort(port, 6);
result = check(sp_blocking_write(port, &bytes1, bufsize1, timeout));
printf("Attempting to receive response\n");
WaitForEventOnPort(port, 5);
bytesWaiting = sp_input_waiting(port);
if (bytesWaiting > 0)
{
memset(buf, 0, sizeof(buf));
//printf("bytes found on port\n");
retval = sp_blocking_read(port, buf, sizeof(buf)-1, 10);
if (retval < 0)
{
printf("Error reading from serial port: %d\r\n", retval);
retval = -1;
break;
}
else
{
for(i=0; i<retval; i++)
{
printf("%c", buf[i]);
if (buf[i] == 13)
{
count++;
}
}
int ret = atoi(buf);
*numlights = ret;
return retval;
}
}
else
if (bytesWaiting < 0)
{
printf("Error getting bytes available from serial port: %d\r\n", bytesWaiting);
retval = -1;
break;
}
printf("didn't get nothing\n");
//count++;
retval = 0;
}
return retval;
}
int main()
{
char* port_name = "/dev/simdev0";
char* port_name = "/dev/ttyACM0";
/* The ports we will use. */
struct sp_port* port;
@ -18,9 +165,9 @@ int main()
/* Open and configure each port. */
printf("Looking for port %s.\n", port_name);
check(sp_get_port_by_name(port_name, &port));
printf("Using %s\r\n", sp_get_port_name(port));
printf("Opening port.\n");
check(sp_open(port, SP_MODE_READ_WRITE));
check(sp_open(port, SP_MODE_READ | SP_MODE_WRITE));
printf("Setting port to 115200 8N1, no flow control.\n");
check(sp_set_baudrate(port, 115200));
@ -28,59 +175,16 @@ int main()
check(sp_set_parity(port, SP_PARITY_NONE));
check(sp_set_stopbits(port, 1));
check(sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE));
check(sp_set_rts(port, 1));
check(sp_set_dtr(port, 1));
ShiftLightsData sd;
size_t bufsize1 = 11;
size_t recv_bufsize1 = 5;
char recv_buf1[recv_bufsize1];
char bytes1[bufsize1];
for(int j = 0; j < bufsize1; j++)
{
bytes1[j] = 0x00;
}
bytes1[0] = 0xff;
bytes1[1] = 0xff;
bytes1[2] = 0xff;
bytes1[3] = 0xff;
bytes1[4] = 0xff;
bytes1[5] = 0xff;
bytes1[6] = 0x6c;
bytes1[7] = 0x65;
bytes1[8] = 0x64;
bytes1[9] = 0x73;
bytes1[10] = 0x63;
int result = 0;
unsigned int timeout = 2000;
result = check(sp_blocking_write(port, &bytes1, bufsize1, timeout));
sleep(2);
result = check(sp_blocking_read(port, &recv_buf1, recv_bufsize1, timeout));
sleep(2);
char numstr[recv_bufsize1];
for(int j = 0; j < recv_bufsize1; j++)
{
numstr[j] = '\0';
}
for(int j = 0; j < recv_bufsize1; j++)
{
printf("%02x\n", recv_buf1[j]);
if(recv_buf1[j] != 0 && recv_buf1[j] != 0x0d && recv_buf1[j] != 0x0a)
{
numstr[j] = recv_buf1[j];
}
}
int numlights = atoi(numstr);
printf("numlights is %s %i\n", numstr, numlights);
//printf("%x\n", recv_buf[0]);
//printf("%x\n", recv_buf[1]);
//printf("%x\n", recv_buf[2]);
//printf("%x\n", recv_buf[3]);
//printf("%x\n", recv_buf[4]);
int numlights = 0;
result = ReadFromPort(port, &numlights);
int timeout = 2000;
size_t bufsize = (numlights * 3) + 14;
char bytes[bufsize];
for(int j = 0; j < bufsize; j++)
@ -133,30 +237,4 @@ int main()
sp_free_port(port);
}
/* Helper function for error handling. */
int check(enum sp_return result)
{
/* For this example we'll just exit on any error by calling abort(). */
char* error_message;
switch (result)
{
case SP_ERR_ARG:
printf("Error: Invalid argument.\n");
abort();
case SP_ERR_FAIL:
error_message = sp_last_error_message();
printf("Error: Failed: %s\n", error_message);
sp_free_error_message(error_message);
abort();
case SP_ERR_SUPP:
printf("Error: Not supported.\n");
abort();
case SP_ERR_MEM:
printf("Error: Couldn't allocate memory.\n");
abort();
case SP_OK:
default:
return result;
}
}