Add support for simhub protocol and custom lua scripts to control leds

This commit is contained in:
Paul Dino Jones 2025-02-25 18:41:10 -05:00
parent d0f4a48c35
commit 9c0cadffdf
14 changed files with 847 additions and 32 deletions

View File

@ -1,6 +1,6 @@
# minimum CMake version required for C++20 support, among other things # minimum CMake version required for C++20 support, among other things
cmake_minimum_required(VERSION 3.15) cmake_minimum_required(VERSION 3.18)
# detect if Monocoque is being used as a sub-project of another CMake project # detect if Monocoque is being used as a sub-project of another CMake project
if(NOT DEFINED PROJECT_NAME) if(NOT DEFINED PROJECT_NAME)
@ -37,10 +37,10 @@ add_executable(monocoque src/monocoque/monocoque.c)
if(USE_PULSEAUDIO) if(USE_PULSEAUDIO)
message("Using pulseaudio backend...") message("Using pulseaudio backend...")
add_compile_definitions(USE_PULSEAUDIO=true) add_compile_definitions(USE_PULSEAUDIO=true)
target_link_libraries(monocoque m hidapi-hidraw pulse serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir) target_link_libraries(monocoque m hidapi-hidraw pulse serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir lua5.4)
else() else()
message("Using portaudio backend...") message("Using portaudio backend...")
target_link_libraries(monocoque m hidapi-hidraw portaudio serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir) target_link_libraries(monocoque m hidapi-hidraw portaudio serialport xml2 argtable2 config gameloop helper devices slog simulatorapi uv xdg-basedir lua5.4)
endif() endif()
target_include_directories(monocoque PUBLIC config ${LIBXML_INCLUDE_DIR}) target_include_directories(monocoque PUBLIC config ${LIBXML_INCLUDE_DIR})
@ -96,10 +96,10 @@ add_subdirectory(src/monocoque/slog)
#target_link_libraries(hidtest hidapi-hidraw) #target_link_libraries(hidtest hidapi-hidraw)
#add_test(hidtest hidtest) #add_test(hidtest hidtest)
# #
#add_executable(simlighttest tests/simlighttest.c) add_executable(simlighttest tests/simlighttest.c)
#target_include_directories(simlighttest PUBLIC) target_include_directories(simlighttest PUBLIC)
#target_link_libraries(simlighttest serialport) target_link_libraries(simlighttest serialport)
#add_test(simlighttest simlighttest) add_test(simlighttest simlighttest)
# used for enabling additional compiler options if supported # used for enabling additional compiler options if supported

View File

@ -34,6 +34,8 @@ set(devices_source_files
sound/usb_generic_shaker_pulse.c sound/usb_generic_shaker_pulse.c
serial/arduino.h serial/arduino.h
serial/arduino.c serial/arduino.c
serial/arduinoledlua.h
serial/arduinoledlua.c
serial/moza.h serial/moza.h
serial/moza.c serial/moza.c
) )

View File

@ -2,13 +2,37 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.h>
#include "arduino.h" #include "arduino.h"
#include "arduinoledlua.h"
#include "../serialadapter.h" #include "../serialadapter.h"
#include "../../slog/slog.h" #include "../../slog/slog.h"
#define arduino_timeout 5000 #define arduino_timeout 5000
int arduino_check(enum sp_return result)
{
char* error_message;
switch (result)
{
case SP_ERR_ARG:
return 1;
case SP_ERR_FAIL:
error_message = sp_last_error_message();
sloge("error: serial write failed: %s", error_message);
sp_free_error_message(error_message);
case SP_ERR_SUPP:
printf("Error: Not supported.\n");
case SP_ERR_MEM:
printf("Error: Couldn't allocate memory.\n");
case SP_OK:
default:
return result;
}
}
int arduino_update(SerialDevice* serialdevice, void* data, size_t size) int arduino_update(SerialDevice* serialdevice, void* data, size_t size)
{ {
int result = 1; int result = 1;
@ -23,3 +47,285 @@ int arduino_init(SerialDevice* serialdevice, const char* portdev)
serialdevice->id = monocoque_serial_open(serialdevice, portdev); serialdevice->id = monocoque_serial_open(serialdevice, portdev);
return serialdevice->id; 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 result = 0;
unsigned int timeout = 2000;
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);
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);
if(luafile == NULL)
{
return serialdevice->id;
}
lua_State* L = luaL_newstate();
luaL_openlibs(L);
int top=lua_gettop(L);
int status = luaL_loadfile(L, luafile);
if (status) {
/* If something went wrong, error message is at the top of */
/* the stack */
fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));
exit(1);
}
lua_setglobal(L,"myFunc");
serialdevice->L = L;
return serialdevice->id;
}
int arduino_simled_update(SimDevice* this, SimData* simdata)
{
SerialDevice* serialdevice = (void *) this->derived;
int result = 1;
int total_leds = serialdevice->numleds;
size_t bufsize = (total_leds * 3) + 14;
char bytes[bufsize];
int endled = serialdevice->endled;
int startled = serialdevice->startled;
if(endled == 0)
{
endled = total_leds;
}
int num_avail_leds = endled - startled + 1;
int rpm = simdata->rpms;
int maxrpm = simdata->maxrpm;
int litleds = 0;
if(rpm > 0 && maxrpm > 0)
{
int rpmmargin = ceil(.05*maxrpm);
int rpminterval = (maxrpm-rpmmargin) / (num_avail_leds);
for (int l = 1; l <= (num_avail_leds); l++)
{
if(rpm >= (rpminterval * l))
{
litleds = l;
}
}
for(int j = 0; j < bufsize; j++)
{
bytes[j] = 0x00;
}
bytes[0] = 0xff;
bytes[1] = 0xff;
bytes[2] = 0xff;
bytes[3] = 0xff;
bytes[4] = 0xff;
bytes[5] = 0xff;
bytes[6] = 0x73;
bytes[7] = 0x6c;
bytes[8] = 0x65;
bytes[9] = 0x64;
bytes[10] = 0x73;
bytes[bufsize-1] = 0xfd;
bytes[bufsize-2] = 0xfe;
bytes[bufsize-3] = 0xff;
for(int i = 0; i < litleds; i++)
{
if(i < ((num_avail_leds) / 2))
{
//green
bytes[11 + ((i + startled - 1) * 3) + 1] = 0xff;
}
else
{
if(i < num_avail_leds - 1)
{
//yellow
bytes[11 + ((i + startled - 1) * 3) + 0] = 0xff;
bytes[11 + ((i + startled - 1) * 3) + 1] = 0xff;
}
}
if(i == num_avail_leds - 1)
{
//red
bytes[11 + ((i + startled - 1) * 3) + 0] = 0xff;
}
}
}
slogt("Updating arduino device lights to %i", litleds);
// we can add configs to set all the colors
size_t size = sizeof(bytes);
result = monocoque_serial_write(serialdevice->id, &bytes, size, arduino_timeout);
return result;
}
int arduino_customled_update(SimDevice* this, SimData* simdata)
{
SerialDevice* serialdevice = (void *) this->derived;
int result = 1;
int total_leds = serialdevice->numleds;
size_t bufsize = (total_leds * 3) + 14;
char bytes[bufsize];
for(int j = 0; j < bufsize; j++)
{
bytes[j] = 0x00;
}
bytes[0] = 0xff;
bytes[1] = 0xff;
bytes[2] = 0xff;
bytes[3] = 0xff;
bytes[4] = 0xff;
bytes[5] = 0xff;
bytes[6] = 0x73;
bytes[7] = 0x6c;
bytes[8] = 0x65;
bytes[9] = 0x64;
bytes[10] = 0x73;
bytes[bufsize-1] = 0xfd;
bytes[bufsize-2] = 0xfe;
bytes[bufsize-3] = 0xff;
lua_State* L = serialdevice->L;
lua_pushstring(L, "buff");
lua_pushlightuserdata(L, &bytes);
lua_settable(L, LUA_REGISTRYINDEX);
simdata_to_lua(L, simdata);
lua_setglobal(L, "simdata");
lua_pushinteger(L, total_leds);
lua_setglobal(L, "TotalLeds");
lua_register(L, "set_led_to_color", set_led_to_color);
lua_register(L, "set_led_range_to_color", set_led_range_to_color);
lua_register(L, "set_led_to_rgb_color", set_led_to_rgb_color);
lua_register(L, "set_led_range_to_rgb_color", set_led_range_to_rgb_color);
lua_register(L, "led_clear_all", led_clear_all);
lua_pushinteger(L, LUALEDCOLOR_RED);
lua_setglobal(L, "RED");
lua_pushinteger(L, LUALEDCOLOR_GREEN);
lua_setglobal(L, "GREEN");
lua_pushinteger(L, LUALEDCOLOR_BLUE);
lua_setglobal(L, "BLUE");
lua_pushinteger(L, LUALEDCOLOR_YELLOW);
lua_setglobal(L, "YELLOW");
lua_pushinteger(L, LUALEDCOLOR_ORANGE);
lua_setglobal(L, "ORANGE");
lua_getglobal(L,"myFunc");
if (lua_pcall(L, 0, 0, 0) != LUA_OK)
{
fprintf(stderr, "Error calling Lua script: %s\n", lua_tostring(L, -1));
}
size_t size = sizeof(bytes);
arduino_update(serialdevice, &bytes, size);
// move to free
return result;
}
int arduino_customled_free(SerialDevice* serialdevice, bool lua)
{
size_t bufsize = (serialdevice->numleds * 3) + 14;
char bytes[bufsize];
int endled = serialdevice->endled;
int startled = serialdevice->startled;
if(endled == 0)
for(int j = 0; j < bufsize; j++)
{
bytes[j] = 0x00;
}
bytes[0] = 0xff;
bytes[1] = 0xff;
bytes[2] = 0xff;
bytes[3] = 0xff;
bytes[4] = 0xff;
bytes[5] = 0xff;
bytes[6] = 0x73;
bytes[7] = 0x6c;
bytes[8] = 0x65;
bytes[9] = 0x64;
bytes[10] = 0x73;
bytes[bufsize-1] = 0xfd;
bytes[bufsize-2] = 0xfe;
bytes[bufsize-3] = 0xff;
for(int i = 0; i < serialdevice->numleds; i++)
{
bytes[11 + (i * 3) + 0] = 0x00;
bytes[11 + (i * 3) + 1] = 0x00;
bytes[11 + (i * 3) + 2] = 0x00;
}
size_t size = sizeof(bytes);
int result = monocoque_serial_write(serialdevice->id, &bytes, size, arduino_timeout);
if(lua == true)
{
lua_close(serialdevice->L);
}
return result;
}

View File

@ -5,8 +5,12 @@
#include "../serialdevice.h" #include "../serialdevice.h"
int arduino_simled_update(SimDevice* this, SimData* simdata);
int arduino_update(SerialDevice* serialdevice, void* data, size_t size); int arduino_update(SerialDevice* serialdevice, void* data, size_t size);
int arduino_customled_init(SerialDevice* serialdevice, const char* portdev, const char* luafile);
int arduino_customled_update(SimDevice* this, SimData* simdata);
int arduino_init(SerialDevice* serialdevice, const char* portdev); int arduino_init(SerialDevice* serialdevice, const char* portdev);
int arduino_free(SerialDevice* serialdevice); int arduino_free(SerialDevice* serialdevice);
int arduino_customled_free(SerialDevice* serialdevice, bool lua);
#endif #endif

View File

@ -0,0 +1,302 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "arduinoledlua.h"
#include "arduino.h"
#include "../../slog/slog.h"
int simdata_to_lua(lua_State *L, SimData* simdata) {
lua_newtable(L);
lua_pushinteger(L, simdata->playerflag);
lua_setfield(L, -2, "playerflag");
lua_pushinteger(L, simdata->rpms);
lua_setfield(L, -2, "rpm");
lua_pushinteger(L, simdata->maxrpm);
lua_setfield(L, -2, "maxrpm");
return 1; // Return the table to Lua
}
uint8_t get_color_rgb_value(int color, int rgb)
{
switch (color)
{
case LUALEDCOLOR_RED:
switch (rgb)
{
case 0:
return 255;
case 1:
return 0;
case 2:
return 0;
}
case LUALEDCOLOR_GREEN:
switch (rgb)
{
case 0:
return 0;
case 1:
return 255;
case 2:
return 0;
}
case LUALEDCOLOR_BLUE:
switch (rgb)
{
case 0:
return 0;
case 1:
return 0;
case 2:
return 255;
}
case LUALEDCOLOR_YELLOW:
switch (rgb)
{
case 0:
return 255;
case 1:
return 255;
case 2:
return 0;
}
case LUALEDCOLOR_ORANGE:
switch (rgb)
{
case 0:
return 255;
case 1:
return 165;
case 2:
return 0;
}
default:
return 0;
}
}
int set_led_range_to_color(lua_State *L)
{
slogt("lua called c function set_led_range_to_color");
int range_start = lua_tonumber(L, 1);
int range_end = lua_tonumber(L, 2);
int color = lua_tonumber(L, 3);
slogd("lua range start is %i", range_start);
slogd("lua range end is %i", range_end);
slogd("lua color is %i", color);
range_start = range_start - 1;
lua_getglobal(L, "TotalLeds");
int numlights = 0;
if (lua_isnumber(L, -1))
{
numlights = lua_tonumber(L, -1);
}
slogd("num leds is %i", numlights);
if(range_end > numlights)
{
range_end = numlights;
}
if(range_end == 0)
{
slogt("Invalid range, doing nothing");
return 1;
}
lua_pushstring(L, "buff");
lua_gettable(L, LUA_REGISTRYINDEX);
char* bytes = lua_touserdata(L, -1);
slogt("tenth byte of buff is x%02x", bytes[10]);
uint8_t color0 = get_color_rgb_value(color, 0);
uint8_t color1 = get_color_rgb_value(color, 1);
uint8_t color2 = get_color_rgb_value(color, 2);
for( int i = range_start; i < range_end; i++)
{
bytes[(i * 3) + 11 + 0] = color0;
bytes[(i * 3) + 11 + 1] = color1;
bytes[(i * 3) + 11 + 2] = color2;
}
}
int set_led_range_to_rgb_color(lua_State *L)
{
slogt("lua called c function set_led_range_to_rgb_color");
int range_start = lua_tonumber(L, 1);
int range_end = lua_tonumber(L, 2);
int color0 = lua_tonumber(L, 3);
int color1 = lua_tonumber(L, 4);
int color2 = lua_tonumber(L, 5);
slogd("lua range start is %i", range_start);
slogd("lua range end is %i", range_end);
slogd("lua color0 is %i", color0);
slogd("lua color1 is %i", color1);
slogd("lua color2 is %i", color2);
range_start = range_start - 1;
lua_getglobal(L, "TotalLeds");
int numlights = 0;
if (lua_isnumber(L, -1))
{
numlights = lua_tonumber(L, -1);
}
slogd("num leds is %i", numlights);
if(range_end > numlights)
{
range_end = numlights;
}
if(range_end == 0)
{
return 1;
}
lua_pushstring(L, "buff");
lua_gettable(L, LUA_REGISTRYINDEX);
char* bytes = lua_touserdata(L, -1);
slogt("tenth byte of buff is x%02x", bytes[10]);
for( int i = range_start; i < range_end; i++)
{
bytes[(i * 3) + 11 + 0] = color0;
bytes[(i * 3) + 11 + 1] = color1;
bytes[(i * 3) + 11 + 2] = color2;
}
}
int set_led_to_color(lua_State *L)
{
slogt("lua called c function set_led_to_rgb_color");
int led = lua_tonumber(L, 1);
int color = lua_tonumber(L, 2);
slogd("lua led is %i", led);
slogd("lua color is %i", color);
led = led - 1;
lua_getglobal(L, "TotalLeds");
int numlights = 0;
if (lua_isnumber(L, -1))
{
numlights = lua_tonumber(L, -1);
}
slogd("num leds is %i", numlights);
if(led > numlights)
{
return 1;
}
lua_pushstring(L, "buff");
lua_gettable(L, LUA_REGISTRYINDEX);
char* bytes = lua_touserdata(L, -1);
slogt("tenth byte of buff is x%02x", bytes[10]);
uint8_t color0 = get_color_rgb_value(color, 0);
uint8_t color1 = get_color_rgb_value(color, 1);
uint8_t color2 = get_color_rgb_value(color, 2);
bytes[(led * 3) + 11 + 0] = color0;
bytes[(led * 3) + 11 + 1] = color1;
bytes[(led * 3) + 11 + 2] = color2;
}
int set_led_to_rgb_color(lua_State *L)
{
slogt("lua called c function set_led_to_rgb_color");
int led = lua_tonumber(L, 1);
int color0 = lua_tonumber(L, 2);
int color1 = lua_tonumber(L, 3);
int color2 = lua_tonumber(L, 4);
slogd("lua led is %i", led);
slogd("lua color0 is %i", color0);
slogd("lua color1 is %i", color1);
slogd("lua color2 is %i", color2);
led = led - 1;
lua_getglobal(L, "TotalLeds");
int numlights = 0;
if (lua_isnumber(L, -1))
{
numlights = lua_tonumber(L, -1);
}
slogd("num leds is %i", numlights);
if(led > numlights)
{
return 1;
}
lua_pushstring(L, "buff");
lua_gettable(L, LUA_REGISTRYINDEX);
char* bytes = lua_touserdata(L, -1);
slogt("tenth byte of buff is x%02x", bytes[10]);
bytes[(led * 3) + 11 + 0] = color0;
bytes[(led * 3) + 11 + 1] = color1;
bytes[(led * 3) + 11 + 2] = color2;
}
int led_clear_all(lua_State *L)
{
slogt("lua called c function led_clear_all");
lua_getglobal(L, "TotalLeds");
int numlights = 0;
if (lua_isnumber(L, -1))
{
numlights = lua_tonumber(L, -1);
}
slogd("num leds is %i", numlights);
lua_pushstring(L, "buff");
lua_gettable(L, LUA_REGISTRYINDEX);
char* bytes = lua_touserdata(L, -1);
slogt("tenth byte of buff is x%02x", bytes[10]);
for( int i = 0; i < numlights; i++)
{
bytes[(i * 3) + 11 + 0] = 0x00;
bytes[(i * 3) + 11 + 1] = 0x00;
bytes[(i * 3) + 11 + 2] = 0x00;
}
}

View File

@ -0,0 +1,25 @@
#ifndef _ARDUINOLEDLUA_H
#define _ARDUINOLEDLUA_H
#include "lua5.4/lua.h"
#include "lua5.4/lauxlib.h"
#include "lua5.4/lualib.h"
#include "../../simulatorapi/simapi/simapi/simdata.h"
typedef enum {
LUALEDCOLOR_RED = 1,
LUALEDCOLOR_GREEN,
LUALEDCOLOR_BLUE,
LUALEDCOLOR_YELLOW,
LUALEDCOLOR_ORANGE,
} LUALEDColor;
int simdata_to_lua(lua_State *L, SimData* simdata);
int set_led_range_to_color(lua_State *L);
int set_led_to_color(lua_State *L);
int set_led_range_to_rgb_color(lua_State *L);
int set_led_to_rgb_color(lua_State *L);
int led_clear_all(lua_State *L);
#endif

View File

@ -128,6 +128,36 @@ int monocoque_serial_write_block(uint8_t serialdevicenum, void* data, size_t siz
return result; return result;
} }
int monocoque_serial_read_block(uint8_t serialdevicenum, void* data, size_t size, int timeout)
{
slogt("serial device id %i", serialdevicenum);
monocoque_serial_device monocoque_serial_dev = monocoque_serial_devices[serialdevicenum];
slogt("port name: %s, busy %i, open %i, openfail %i", monocoque_serial_dev.portname, monocoque_serial_dev.busy, monocoque_serial_dev.open, monocoque_serial_dev.busy);
if(monocoque_serial_dev.port == NULL)
{
sloge("port is null");
}
int result = -1;
if(monocoque_serial_dev.open == true)
{
while(monocoque_serial_dev.busy == true)
{
slogt("hopefully this doesn't happen long");
continue;
}
monocoque_serial_dev.busy = true;
result = sp_blocking_read(monocoque_serial_dev.port, data, size, timeout);
slogi("actually performed read");
}
monocoque_serial_dev.busy = false;
return result;
}
int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev) int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev)
{ {
int serial_device_num = -1; int serial_device_num = -1;
@ -173,6 +203,7 @@ int monocoque_serial_open(SerialDevice* serialdevice, const char* portdev)
error = check(sp_get_port_by_name(port_name, &sp)); error = check(sp_get_port_by_name(port_name, &sp));
if (error != 0) if (error != 0)
{ {
sloge("Error opening serial port");
monocoque_serial_devices[i].open = false; monocoque_serial_devices[i].open = false;
monocoque_serial_devices[i].openfail = true; monocoque_serial_devices[i].openfail = true;
return -1; return -1;

View File

@ -22,6 +22,7 @@ static monocoque_serial_device monocoque_serial_devices[10];
int monocoque_serial_write(uint8_t serialdevicenum, void* data, size_t size, int timeout); 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_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);
int monocoque_serial_open(SerialDevice* serialdevice, const char* port); int monocoque_serial_open(SerialDevice* serialdevice, const char* port);
int monocoque_serial_free(SerialDevice* serialdevice); int monocoque_serial_free(SerialDevice* serialdevice);

View File

@ -70,6 +70,8 @@ int arduino_shiftlights_update(SimDevice* this, SimData* simdata)
return result; return result;
} }
int arduino_simwind_update(SimDevice* this, SimData* simdata) int arduino_simwind_update(SimDevice* this, SimData* simdata)
{ {
SerialDevice* serialdevice = (void *) this->derived; SerialDevice* serialdevice = (void *) this->derived;
@ -151,6 +153,13 @@ int serialdev_free(SimDevice* this)
size_t size = sizeof(SimHapticData); size_t size = sizeof(SimHapticData);
monocoque_serial_write_block(serialdevice->id, &serialdevice->u.simhapticdata, size, 9000); monocoque_serial_write_block(serialdevice->id, &serialdevice->u.simhapticdata, size, 9000);
slogi("set zero to arduino device"); slogi("set zero to arduino device");
break;
case ARDUINODEV__SIMLED__CUSTOM:
arduino_customled_free(serialdevice, true);
break;
case ARDUINODEV__SIMLED:
arduino_customled_free(serialdevice, false);
break;
} }
@ -181,15 +190,20 @@ int serialdev_init(SerialDevice* serialdevice, DeviceSettings* ds)
serialdevice->motorsposition = ds->serialdevsettings.motorsposition; serialdevice->motorsposition = ds->serialdevsettings.motorsposition;
serialdevice->baudrate = ds->serialdevsettings.baud; serialdevice->baudrate = ds->serialdevsettings.baud;
switch (serialdevice->type) switch (serialdevice->devicetype)
{ {
case SERIALDEV_WHEEL: case SERIALDEV__MOZAR5:
// the wheel stuff assumed it was a usb // the wheel stuff assumed it was a usb
//error = wheeldev_init(&serialdevice->u.wheeldevice, ds); //error = wheeldev_init(&serialdevice->u.wheeldevice, ds);
// maybe this call a more generic serial wheel init first
error = moza_init(serialdevice, ds->serialdevsettings.portdev); error = moza_init(serialdevice, ds->serialdevsettings.portdev);
break; break;
case ARDUINODEV__SIMLED__CUSTOM:
error = arduino_customled_init(serialdevice, ds->serialdevsettings.portdev, ds->serialdevsettings.config_file);
break;
case ARDUINODEV__SIMLED:
error = arduino_customled_init(serialdevice, ds->serialdevsettings.portdev, NULL);
break;
default: default:
error = arduino_init(serialdevice, ds->serialdevsettings.portdev); error = arduino_init(serialdevice, ds->serialdevsettings.portdev);
break; break;
@ -201,6 +215,8 @@ int serialdev_init(SerialDevice* serialdevice, DeviceSettings* ds)
static const vtable serial_simdevice_vtable = { &serialdev_update, &serialdev_free }; static const vtable serial_simdevice_vtable = { &serialdev_update, &serialdev_free };
static const vtable arduino_shiftlights_vtable = { &arduino_shiftlights_update, &serialdev_free }; static const vtable arduino_shiftlights_vtable = { &arduino_shiftlights_update, &serialdev_free };
static const vtable arduino_simled_vtable = { &arduino_simled_update, &serialdev_free };
static const vtable arduino_simled_custom_vtable = { &arduino_customled_update, &serialdev_free };
static const vtable arduino_simwind_vtable = { &arduino_simwind_update, &serialdev_free }; static const vtable arduino_simwind_vtable = { &arduino_simwind_update, &serialdev_free };
static const vtable arduino_simhaptic_vtable = { &arduino_simhaptic_update, &serialdev_free }; static const vtable arduino_simhaptic_vtable = { &arduino_simhaptic_update, &serialdev_free };
static const vtable serialwheel_vtable = { &serial_wheel_update, &serial_wheel_free }; static const vtable serialwheel_vtable = { &serial_wheel_update, &serial_wheel_free };
@ -223,6 +239,26 @@ SerialDevice* new_serial_device(DeviceSettings* ds, MonocoqueSettings* ms) {
this->m.vtable = &arduino_shiftlights_vtable; this->m.vtable = &arduino_shiftlights_vtable;
slogi("Initializing arduino device for shiftlights."); slogi("Initializing arduino device for shiftlights.");
break; break;
case (SIMDEVTYPE_SIMLED):
if(ds->has_config == true)
{
this->devicetype = ARDUINODEV__SIMLED__CUSTOM;
this->startled = ds->serialdevsettings.startled;
this->endled = ds->serialdevsettings.endled;
this->m.vtable = &arduino_simled_custom_vtable;
slogi("Initializing arduino device for custom simled.");
}
else
{
this->devicetype = ARDUINODEV__SIMLED;
this->numleds = ds->serialdevsettings.numleds;
this->startled = ds->serialdevsettings.startled;
this->endled = ds->serialdevsettings.endled;
this->m.vtable = &arduino_simled_vtable;
slogi("Initializing arduino device for simled.");
}
break;
case (SIMDEVTYPE_SIMWIND): case (SIMDEVTYPE_SIMWIND):
this->devicetype = ARDUINODEV__SIMWIND; this->devicetype = ARDUINODEV__SIMWIND;
this->m.vtable = &arduino_simwind_vtable; this->m.vtable = &arduino_simwind_vtable;

View File

@ -10,6 +10,8 @@ typedef enum
ARDUINODEV__SIMWIND = 1, ARDUINODEV__SIMWIND = 1,
ARDUINODEV__HAPTIC = 2, ARDUINODEV__HAPTIC = 2,
SERIALDEV__MOZAR5 = 3, SERIALDEV__MOZAR5 = 3,
ARDUINODEV__SIMLED = 4,
ARDUINODEV__SIMLED__CUSTOM = 5
} }
SerialDeviceType; SerialDeviceType;

View File

@ -3,6 +3,8 @@
#include <stdbool.h> #include <stdbool.h>
#include "lua5.4/lua.h"
#include "usbdevice.h" #include "usbdevice.h"
#include "sounddevice.h" #include "sounddevice.h"
#include "serialdevice.h" #include "serialdevice.h"
@ -49,10 +51,14 @@ typedef struct
int id; int id;
SerialType type; SerialType type;
struct sp_port* port; struct sp_port* port;
lua_State* L;
SerialDeviceType devicetype; SerialDeviceType devicetype;
// move these two they only apply to the haptic device // move these two they only apply to the haptic device
int motorsposition; int motorsposition;
int numlights; int numlights;
int numleds;
int startled;
int endled;
int baudrate; int baudrate;
double ampfactor; double ampfactor;
double state; double state;

View File

@ -145,6 +145,11 @@ int strtodevsubtype(const char* device_subtype, DeviceSettings* ds, int simdev)
ds->dev_subtype = SIMDEVTYPE_SHIFTLIGHTS; ds->dev_subtype = SIMDEVTYPE_SHIFTLIGHTS;
break; break;
} }
if (strcicmp(device_subtype, "Simleds") == 0)
{
ds->dev_subtype = SIMDEVTYPE_SIMLED;
break;
}
if (strcicmp(device_subtype, "SimWind") == 0) if (strcicmp(device_subtype, "SimWind") == 0)
{ {
ds->dev_subtype = SIMDEVTYPE_SIMWIND; ds->dev_subtype = SIMDEVTYPE_SIMWIND;
@ -748,6 +753,18 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co
config_setting_lookup_int(device_settings, "numlights", &numlights); config_setting_lookup_int(device_settings, "numlights", &numlights);
ds->serialdevsettings.numlights = numlights; ds->serialdevsettings.numlights = numlights;
int numleds = 6;
config_setting_lookup_int(device_settings, "numleds", &numleds);
ds->serialdevsettings.numleds = numleds;
int startled = 1;
config_setting_lookup_int(device_settings, "startled", &startled);
ds->serialdevsettings.startled = startled;
int endled = 1;
config_setting_lookup_int(device_settings, "endled", &endled);
ds->serialdevsettings.endled = endled;
int baud = 9600; int baud = 9600;
config_setting_lookup_int(device_settings, "baud", &baud); config_setting_lookup_int(device_settings, "baud", &baud);
ds->serialdevsettings.baud = baud; ds->serialdevsettings.baud = baud;
@ -758,6 +775,21 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co
ds->serialdevsettings.ampfactor = ampfactor; ds->serialdevsettings.ampfactor = ampfactor;
slogt("set port baud rate to %i, ampfactor %f", baud, ampfactor); slogt("set port baud rate to %i, ampfactor %f", baud, ampfactor);
ds->has_config = false;
const char* temp2;
found = config_setting_lookup_string(device_settings, "config", &temp2);
slogt("config is %s found is %i", temp2, found);
if(strcicmp(temp2, "none") == 0)
{
slogt("config set to none");
}
else
{
ds->has_config = true;
ds->serialdevsettings.config_file = strdup(temp2);
slogt("will try to load config file at %s", ds->serialdevsettings.config_file);
}
} }
} }
@ -827,7 +859,7 @@ int uiloadconfig(const char* config_file_str, int confignum, int configureddevic
int settingsfree(DeviceSettings ds) int settingsfree(DeviceSettings ds)
{ {
if (ds.dev_subtype == SIMDEVTYPE_SIMWIND || ds.dev_subtype == SIMDEVTYPE_SHIFTLIGHTS) if (ds.dev_subtype == SIMDEVTYPE_SIMWIND || ds.dev_subtype == SIMDEVTYPE_SHIFTLIGHTS || ds.dev_subtype == SIMDEVTYPE_SIMLED)
{ {
if (ds.serialdevsettings.portdev != NULL) if (ds.serialdevsettings.portdev != NULL)
{ {

View File

@ -29,7 +29,8 @@ typedef enum
SIMDEVTYPE_SIMWIND = 4, SIMDEVTYPE_SIMWIND = 4,
SIMDEVTYPE_SERIALHAPTIC = 5, SIMDEVTYPE_SERIALHAPTIC = 5,
SIMDEVTYPE_USBWHEEL = 6, SIMDEVTYPE_USBWHEEL = 6,
SIMDEVTYPE_SERIALWHEEL = 7 SIMDEVTYPE_SERIALWHEEL = 7,
SIMDEVTYPE_SIMLED = 8
} }
DeviceSubType; DeviceSubType;
@ -153,8 +154,12 @@ TachometerSettings;
typedef struct typedef struct
{ {
char* portdev; char* portdev;
char* config_file;
MotorPosition motorsposition; MotorPosition motorsposition;
int numlights; int numlights;
int numleds;
int startled;
int endled;
float ampfactor; float ampfactor;
int baud; int baud;
} }
@ -195,6 +200,7 @@ typedef struct
VibrationEffectType effect_type; VibrationEffectType effect_type;
MonocoqueTyreIdentifier tyre; MonocoqueTyreIdentifier tyre;
double threshold; double threshold;
bool has_config;
// union? // union?
TachometerSettings tachsettings; TachometerSettings tachsettings;
SerialDeviceSettings serialdevsettings; SerialDeviceSettings serialdevsettings;

View File

@ -10,7 +10,7 @@ int check(enum sp_return result);
int main() int main()
{ {
char* port_name = "/dev/ttyACM0"; char* port_name = "/dev/simdev0";
/* The ports we will use. */ /* The ports we will use. */
struct sp_port* port; struct sp_port* port;
@ -32,39 +32,101 @@ int main()
ShiftLightsData sd; ShiftLightsData sd;
int result;
unsigned int timeout = 2000; size_t bufsize1 = 11;
size_t size = sizeof(ShiftLightsData); size_t recv_bufsize1 = 5;
for( sd.litleds = 0; sd.litleds < 7; sd.litleds++) 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));
result = check(sp_blocking_read(port, &recv_buf1, recv_bufsize1, timeout));
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]);
size_t bufsize = (numlights * 3) + 14;
char bytes[bufsize];
for(int j = 0; j < bufsize; j++)
{
bytes[j] = 0x00;
}
bytes[0] = 0xff;
bytes[1] = 0xff;
bytes[2] = 0xff;
bytes[3] = 0xff;
bytes[4] = 0xff;
bytes[5] = 0xff;
bytes[6] = 0x73;
bytes[7] = 0x6c;
bytes[8] = 0x65;
bytes[9] = 0x64;
bytes[10] = 0x73;
bytes[bufsize-1] = 0xfd;
bytes[bufsize-2] = 0xfe;
bytes[bufsize-3] = 0xff;
for( int i = 0; i < numlights; i++)
{
/* On success, sp_blocking_write() and sp_blocking_read() bytes[(i * 3) + 11 + 1] = 0xff;
* return the number of bytes sent/received before the
* timeout expired. We'll store that result here. */
/* Send data. */ /* Send data. */
result = check(sp_blocking_write(port, &sd, size, timeout)); result = check(sp_blocking_write(port, &bytes, bufsize, timeout));
/* Check whether we sent all of the data. */ /* Check whether we sent all of the data. */
if (result == size) if (result == bufsize)
{ {
printf("Sent %d bytes successfully, %i lit leds.\n", size, sd.litleds); printf("Sent %d bytes successfully, %i lit leds.\n", bufsize, numlights);
} }
else else
{ {
printf("Timed out, %d/%d bytes sent.\n", result, size); printf("Timed out, %d/%d bytes sent.\n", result, bufsize);
} }
sleep(2); sleep(2);
} }
sd.litleds = 0; for( int i = 0; i < numlights; i++)
result = check(sp_blocking_write(port, &sd, size, timeout)); {
bytes[(i * 3) + 11 + 1] = 0x00;
}
result = check(sp_blocking_write(port, &bytes, bufsize, timeout));
check(sp_close(port)); check(sp_close(port));
sp_free_port(port); sp_free_port(port);