From 0780b001f6fe62927ed8555a2129023b0fa6ec3f Mon Sep 17 00:00:00 2001 From: Paul Dino Jones Date: Mon, 20 Oct 2025 19:37:28 -0400 Subject: [PATCH] working custom serial --- conf/custom.lua | 1 + src/arduino/custom/Makefile | 166 +++++++++++++++++++ src/arduino/custom/custom.ino | 30 ++++ src/monocoque/devices/serial/arduino.c | 22 +-- src/monocoque/devices/serial/arduinoledlua.c | 6 + src/monocoque/devices/serialdevice.c | 2 +- src/monocoque/helper/confighelper.c | 2 +- 7 files changed, 217 insertions(+), 12 deletions(-) create mode 100644 conf/custom.lua create mode 100644 src/arduino/custom/Makefile create mode 100644 src/arduino/custom/custom.ino diff --git a/conf/custom.lua b/conf/custom.lua new file mode 100644 index 0000000..97af74a --- /dev/null +++ b/conf/custom.lua @@ -0,0 +1 @@ +Message = simdata.velocity .. ";" .. simdata.gear .. ";" .. simdata.rpm .. ";" diff --git a/src/arduino/custom/Makefile b/src/arduino/custom/Makefile new file mode 100644 index 0000000..bfd2e90 --- /dev/null +++ b/src/arduino/custom/Makefile @@ -0,0 +1,166 @@ +# Makefile for Arduino based scketches +# +# Copyright 2020 Valerio Di Giampietro http://va.ler.io v@ler.io +# MIT License - see License.txt file +# +# This Makefile uses the arduino-cli, the Arduino command line interface +# and has been designed and tested to run on Linux, not on Windows. +# Probably it will run on a Mac, but it has not been tested. +# +# Please note that: +# +# 1. each sketch must reside in his own folder with this Makefile +# +# 2. the main make targets are: +# - all compiles and upload +# - compile compiles only +# - upload upload via serial port, compile if the binary file is +# not available +# - ota upload Over The Air, automatically find the device +# IP address using the IOT_NAME (device hostname) +# - clean clean the build directory +# - find find OTA updatable devices on the local subnet +# - requirements it the file "requirements.txt" exists it will +# install the libraries listed in this file +# +# default is "all" +# +# 3. it gets the name of the sketch using the wildcard make command; +# the name is *.ino; this means that you must have ONLY a file +# with .ino extension, otherwise this makefile will break. This +# also means that you can use this Makefile, almost unmodified, +# for any sketch as long as you keep a single .ino file in each +# folder +# +# 4. you can split your project in multiple files, if you wish, +# using a single .ino file and multiple .h files, that you can +# include in the .ino file with an '#include "myfile.h"' +# directive +# +# Optionally some environment variables can be set: +# +# FQBN Fully Qualified Board Name; if not set in the environment +# it will be assigned a value in this makefile +# +# SERIAL_DEV Serial device to upload the sketch; if not set in the +# environment it will be assigned: +# /dev/ttyUSB0 if it exists, or +# /dev/ttyACM0 if it exists, or +# unknown +# +# IOT_NAME Name of the IOT device; if not set in the environment +# it will be assigned a value in this makefile. This is +# very useful for OTA update, the device will be searched +# on the local subnet using this name +# +# OTA_PORT Port used by OTA update; if not set in the environment +# it will be assigned the default value of 8266 in this +# makefile +# +# OTA_PASS Password used for OTA update; if not set in the environment +# it will be assigned the default value of an empty string +# +# V verbose flag; can be 0 (quiet) or 1 (verbose); if not set +# in the environment it will be assigned a default value +# in this makefile + + +MAKE_DIR := $(PWD) +# +# ----- setup wor Wemos D1 mini ----- +#FQBN ?= esp8266:esp8266:d1_mini +#IOT_NAME ?= esp8266-meteo +#OTA_PORT ?= 8266 +#OTA_PASS ?= +# ----- setup for Arduino Uno +FQBN ?= arduino:avr:uno +# ----- --------------------- +V ?= 0 +VFLAG = + +ifeq "$(V)" "1" +VFLAG =-v +endif + +ifndef SERIAL_DEV + ifneq (,$(wildcard /dev/ttyUSB0)) + SERIAL_DEV = /dev/ttyUSB0 + else ifneq (,$(wildcard /dev/ttyACM0)) + SERIAL_DEV = /dev/ttyACM0 + else + SERIAL_DEV = unknown + endif +endif + +BUILD_DIR := $(subst :,.,build/$(FQBN)) + +SRC := $(wildcard *.ino) +HDRS := $(wildcard *.h) +BIN := $(BUILD_DIR)/$(SRC).bin +ELF := $(BUILD_DIR)/$(SRC).elf + +$(info FQBN is [${FQBN}]) +$(info IOT_NAME is [${IOT_NAME}]) +$(info OTA_PORT is [${OTA_PORT}]) +$(info OTA_PASS is [${OTA_PASS}]) +$(info V is [${V}]) +$(info VFLAG is [${VFLAG}]) +$(info MAKE_DIR is [${MAKE_DIR}]) +$(info BUILD_DIR is [${BUILD_DIR}]) +$(info SRC is [${SRC}]) +$(info HDRS is [${HDRS}]) +$(info BIN is [${BIN}]) +$(info SERIAL_DEV is [${SERIAL_DEV}]) + +all: $(ELF) upload +.PHONY: all + +compile: $(ELF) +.PHONY: compile + +$(ELF): $(SRC) $(HDRS) + arduino-cli compile -b $(FQBN) $(VFLAG) + @if which arduino-manifest.pl; \ + then echo "---> Generating manifest.txt"; \ + arduino-manifest.pl -b $(FQBN) $(SRC) $(HDRS) > manifest.txt; \ + else echo "---> If you want to generate manifest.txt, listing used libraries and their versions,"; \ + echo "---> please install arduino-manifest, see https://github.com/digiampietro/arduino-manifest"; \ + fi + +upload: + @if [ ! -c $(SERIAL_DEV) ] ; \ + then echo "---> ERROR: Serial Device not available, please set the SERIAL_DEV environment variable" ; \ + else echo "---> Uploading sketch\n"; \ + arduino-cli upload -b $(FQBN) -p $(SERIAL_DEV) $(VFLAG); \ + fi + +ota: + @PLAT_PATH=`arduino-cli compile -b $(FQBN) --show-properties | grep '^runtime.platform.path' | awk -F= '{print $$2}'` ; \ + PY_PATH=`arduino-cli compile -b $(FQBN) --show-properties | grep '^runtime.tools.python3.path' | awk -F= '{print $$2}'` ; \ + IOT_IP=`avahi-browse _arduino._tcp --resolve --parsable --terminate|grep -i ';$(IOT_NAME);'|grep ';$(OTA_PORT);'| awk -F\; '{print $$8}'|head -1`; \ + BINFILE=$(wildcard $(BUILD_DIR)/$(SRC)*bin); \ + echo "PLAT_PATH is [$$PLAT_PATH]" ; \ + echo "PY_PATH: is [$$PY_PATH]" ; \ + echo "IOT_IP: is [$$IOT_IP]" ; \ + echo "BINFILE: is [$$BINFILE]" ; \ + if [ "$$IOT_IP" = "" ] ; \ + then echo "Unable to find device IP. Check that the IOT_NAME environment variable is correctly set. Use 'make find' to search devices"; \ + else echo "---> Uploading Over The Air"; \ + $$PY_PATH/python3 $$PLAT_PATH/tools/espota.py -i $$IOT_IP -p $(OTA_PORT) --auth=$(OTA_PASS) -f $$BINFILE ;\ + fi + +clean: + @echo "---> Cleaning the build directory" + rm -rf build + +find: + avahi-browse _arduino._tcp --resolve --parsable --terminate + +requirements: + @if [ -e requirements.txt ]; \ + then while read -r i ; do echo ; \ + echo "---> Installing " '"'$$i'"' ; \ + arduino-cli lib install "$$i" ; \ + done < requirements.txt ; \ + else echo "---> MISSING requirements.txt file"; \ + fi diff --git a/src/arduino/custom/custom.ino b/src/arduino/custom/custom.ino new file mode 100644 index 0000000..0f76b73 --- /dev/null +++ b/src/arduino/custom/custom.ino @@ -0,0 +1,30 @@ +// Called when starting the arduino (setup method in main sketch) +void setup() { + Serial.begin(115200); +} + +// Called when new data is coming from computer +void read() +{ + if(Serial.available()) + { + int speed = Serial.readStringUntil(';').toInt(); + int gear = Serial.readStringUntil(';').toInt(); + int rpms = Serial.readStringUntil(';').toInt(); + //Serial.println("speed: " + String(speed) + " " + "gear: " + String(gear) + " " + "rpms: " + String(rpms)); + } +} + +// Called once per arduino loop, timing can't be predicted, +// but it's called between each command sent to the arduino +void loop() { + read(); +} + +// Called once between each byte read on arduino, +// THIS IS A CRITICAL PATH : +// AVOID ANY TIME CONSUMING ROUTINES !!! +// PREFER READ OR LOOP METHOS AS MUCH AS POSSIBLE +// AVOID ANY INTERRUPTS DISABLE (serial data would be lost!!!) +void idle() { +} diff --git a/src/monocoque/devices/serial/arduino.c b/src/monocoque/devices/serial/arduino.c index ce83549..7e842f3 100644 --- a/src/monocoque/devices/serial/arduino.c +++ b/src/monocoque/devices/serial/arduino.c @@ -177,6 +177,8 @@ int arduino_custom_init(SerialDevice* serialdevice, const char* portdev, const c serialdevice->m.L = L; + slogi("LUA config setup successful."); + return serialdevice->id; } @@ -400,29 +402,29 @@ int arduino_customled_free(SerialDevice* serialdevice, bool lua) int arduino_custom_update(SerialDevice* serialdevice, SimData* simdata) { - size_t bufsize = 14; char bytes[bufsize]; lua_State* L = serialdevice->m.L; - lua_pushstring(L, "buff"); - lua_settable(L, LUA_REGISTRYINDEX); - simdata_to_lua(L, simdata); lua_setglobal(L, "simdata"); - 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)); } + lua_getglobal(L, "Message"); + int result = 0; + if (lua_isstring(L, -1)) { + const char *msg = lua_tostring(L, -1); + size_t size = strlen(msg); + result = arduino_update(serialdevice, (void*) msg, size); + slogt("custom arduino wrote message %s of %i bytes", msg, result); + } - size_t size = sizeof(bytes); - int result = arduino_update(serialdevice, &bytes, size); - - slogt("custom led wrote %i bytes", result); - + // Clean up + lua_pop(L, 1); return result; } diff --git a/src/monocoque/devices/serial/arduinoledlua.c b/src/monocoque/devices/serial/arduinoledlua.c index f2082f8..3fc8dc8 100644 --- a/src/monocoque/devices/serial/arduinoledlua.c +++ b/src/monocoque/devices/serial/arduinoledlua.c @@ -33,6 +33,12 @@ int simdata_to_lua(lua_State *L, SimData* simdata) { lua_pushinteger(L, simdata->rpms); lua_setfield(L, -2, "rpm"); + + lua_pushinteger(L, simdata->gear); + lua_setfield(L, -2, "gear"); + + lua_pushinteger(L, simdata->velocity); + lua_setfield(L, -2, "velocity"); lua_pushinteger(L, simdata->mtick); lua_setfield(L, -2, "mtick"); diff --git a/src/monocoque/devices/serialdevice.c b/src/monocoque/devices/serialdevice.c index 85947b4..2b76fc1 100644 --- a/src/monocoque/devices/serialdevice.c +++ b/src/monocoque/devices/serialdevice.c @@ -308,7 +308,7 @@ SerialDevice* new_serial_device(DeviceSettings* ds, MonocoqueSettings* ms) { break; case (SIMDEVTYPE_ARDUINOCUSTOM): this->devicetype = ARDUINODEV__CUSTOM; - this->m.vtable = &arduino_simwind_vtable; + this->m.vtable = &arduino_custom_vtable; slogi("Initializing custom arduino device."); break; case (SIMDEVTYPE_SERIALHAPTIC): diff --git a/src/monocoque/helper/confighelper.c b/src/monocoque/helper/confighelper.c index 5e8c4e6..810158b 100644 --- a/src/monocoque/helper/confighelper.c +++ b/src/monocoque/helper/confighelper.c @@ -160,7 +160,7 @@ int strtodevsubtype(const char* device_subtype, DeviceSettings* ds, int simdev) ds->dev_subtype = SIMDEVTYPE_SIMLED; break; } - if (strcicmp(device_subtype, "ArduinoCustom") == 0) + if (strcicmp(device_subtype, "ArduinoCustom") == 0 || strcicmp(device_subtype, "Custom") == 0) { ds->dev_subtype = SIMDEVTYPE_ARDUINOCUSTOM; break;