Click here to show a long text explaining the background to my project
I'm connecting real vehicle (German MAN NG272 bus) parts like a dashboard, ticket machine, next stop displays etc to a computer that is running a simulator / game called Omsi 2, which is a bus driving simulator (naturally ![]()
The game has a plugins folder where you place a .dll and a .opl file,
the .dll runs when the game is started and requests data then sends it as a text string via the com port to the arduino, which has connected to it led's, gauges, LCD's etc.
So when a dashboard light turns on or off in the game, the the led / light bulb in the real dashboard does the same, or text that is shown on a ticket printer screen in game is sent to the arduino to display on an LCD in the real ticket machine.
.
The .dll / plugin has to be written by people who want to use this feature, and in the past people have done this, but when ever a new piece of data wants reading the writer of the .dll needs to make changes and re-compile it, along with updating the arduino sketch and the entry in the .opl file.
The .opl file is just a text file that has a list of the names of the data names you want to read.
This means that when people move onto other things and give up on their plugin, we are not able to update things when new data is needed....
usually due to a new bus or map being released for the main game that uses a different name for the function to turn lights on and off etc.
.
A few weeks ago i discovered someone has written a plugin .dll (called Bus Board Interface 2) where he's uploaded the source code to git hub (so if i knew enough about programming i could change it to suit my needs)
But that is not needed so much because he has written it in such a way that it can sort of auto update itself, by reading any new entries you put in the .opl file (and change the arduino code to suit)
The git hub page is here if you want to read it:
https://github.com/Anonim17PL/BBI2
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Can someone have a look through an arduino sketch and help me figure out what is happening in it better please?
The sketch makes the arduino listen to the com port, and when a bus driving simulator game is running it reads text strings sent from the game when a value you want to read changes,
The arduino then reads the text from the string to turn led's on and off, display text on lcd's etc,
and it can also send data from the arduino to the game for switch inputs etc.
The sketch is provided with the .dll that reads out the data from the game, and it's sort of a starter sketch we are to build on to suit our needs.
I got the sketch from : GitHub - Anonim17PL/BBI2: Bus Board Interface 2 (Threaded Edition) for OMSI 2
I've figured out how to add extra triggers to send simple button presses to the game, and how to add more outputs for turning led's on and off,
I'd like to add an LCD to display the text data that comes in the string '$V:0:' amongst other things,
But before i do that, i want to better understand what is going on throughout the sketch, i am very bad at programming / coding, but trying to learn (memory issues do not help me here)
The sketch had zero comments when i got it, so all comment's in the sketch i've added myself to try and figure it out, so i have likely got things very wrong.
I also know that strings and arduino's do not play together well, so i want to switch over to using something like SafeStrings once i know what's going on.
The sketch... all the LCD stuff i added, but i got stuck with where to add the 'LCD.print' functions
// LCD setup stuff
const byte cols = 40; // columns/characters per row
const byte rows = 2; // how many rows
const byte addr = 0x25; // set the LCD address to 0x3F or 0x27
#include <NoiascaLiquidCrystal.h> // use the adopted library downloaded from https://werner.rothschopf.net/202003_arduino_liquid_crystal_umlaute.htm
#include <NoiascaHW/lcd_i2c.h> // include the proper IO interface
LiquidCrystal_I2C_Special lcd(addr, cols, rows); // prints Ä Ö Ü, also activate lcd.createUml() in setup!
// End LCD setup stuff
float varlist[10];
bool prevtriglist[10];
unsigned long buff1;
unsigned long buff2;
float floatroz;
void setup() {
//LCD setup
Wire.begin(); // start I2C library
lcd.begin(); // initialize the LCD
lcd.createUml(); // needed for LiquidCrystal_I2C_Special only - custom characters 5, 6, 7 used for Ä Ö Ü
lcd.backlight(); // turn on backlight
lcd.setCursor(0, 0); // Position cursor top left
lcd.print(F("testing 1..2...3...")); // Print text just to show LCD is working
// End LCD setup
Serial.begin(74800); // Start serial coms
Serial.setTimeout(25);
// Set up pins
// Lights
pinMode(2, OUTPUT); // Indicators
pinMode(3, OUTPUT); // Middle / Rear Door Open
pinMode(4, OUTPUT); // Rear Door Open (bendy Bus)
pinMode(5, OUTPUT); // Stop Req 1
pinMode(6, OUTPUT); // Stop req 2
pinMode(7, OUTPUT); // High Beam light
pinMode(8, OUTPUT); // Battery / No Charge
pinMode(9, OUTPUT); // Low air / Master Failure
pinMode(10, OUTPUT); // Parking Brake
pinMode(11, OUTPUT); // Kneeling
// Switches
pinMode(22, INPUT_PULLUP); // Station Brake
pinMode(23, INPUT_PULLUP); // Door 0
pinMode(24, INPUT_PULLUP); // Door 1
pinMode(25, INPUT_PULLUP); // High Beam
pinMode(26, INPUT_PULLUP); // Kinderwagen Sw
pinMode(27, INPUT_PULLUP); // Horn 1
pinMode(28, INPUT_PULLUP); // Horn 2
// End of set up pins
delay(1000); // Wait 1 second
Serial.write("REFRESH"); // Write to serial
readstr(); // Read initial strings?
}
void sendrequest() { // Not sure
//Serial.print("SL:0");
}
void loop() {
unsigned long currentMillis = millis(); // Millisecond timer
if (currentMillis - buff1 > 2000) { // 2 second timeout, seems to go back to send on change if a switch is held down
buff1 = currentMillis;
sendrequest();
}
while (Serial.available() > 0) { // Do stuff only when serial stream detected?
readstr(); // Read the incoming strings
}
// Read varlist in .opl file, turn relevent led on or off for matching item
analogWrite(2, varlist[0] * 255); // Indicators
analogWrite(3, varlist[1] * 255); // Middle / Rear door open
analogWrite(4, varlist[2] * 255); // Rear Door Open (Bendy Bus)
analogWrite(5, varlist[3] * 255); // Stop Req 1
analogWrite(6, varlist[4] * 255); // Stop Req 2
analogWrite(7, varlist[5] * 255); // High Beam Light
analogWrite(8, varlist[6] * 255); // Battery / No Charge
analogWrite(9, varlist[7] * 255); // Low Air / Master Failure
analogWrite(10, varlist[8] * 255); // Parking Brake
analogWrite(11, varlist[9] * 255); // Kneeling
if (currentMillis - buff2 > 500) { // 1/2 second timeout, to allow sent data to stabilise perhaps?
buff2 = currentMillis;
sendfloatauto(); // Send position of potentiometer on A1, changes position of heater blower speed knob
}
// Buttons / Switches:
// Station brake
if (prevtriglist[0] != !digitalRead(22)) { // Check if data has changed for this trigger
prevtriglist[0] = !digitalRead(22); // If data has changed...
sendtrig(0, prevtriglist[0]); // ....Send new data for this trigger
}
// Door 0
if (prevtriglist[1] != !digitalRead(23)) {
prevtriglist[1] = !digitalRead(23);
sendtrig(1, prevtriglist[1]);
}
// Door 1
if (prevtriglist[2] != !digitalRead(24)) {
prevtriglist[2] = !digitalRead(24);
//sendtrig(2,1);
//delay(60);
//sendtrig(2,0);
sendtrig(2, prevtriglist[2]);
}
// High Beam
if (prevtriglist[3] != !digitalRead(25)) {
prevtriglist[3] = !digitalRead(25);
sendtrig(3, prevtriglist[3]);
}
// Kinderwagen Switch
if (prevtriglist[4] != !digitalRead(26)) {
prevtriglist[4] = !digitalRead(26);
sendtrig(4, prevtriglist[4]);
}
// Horn
if (prevtriglist[5] != !digitalRead(27)) {
prevtriglist[5] = !digitalRead(27);
sendtrig(5, prevtriglist[5]);
}
//
if (prevtriglist[6] != !digitalRead(28)) {
prevtriglist[6] = !digitalRead(28);
sendtrig(6, prevtriglist[6]);
}
}
void readstr() {
String string1 = Serial.readStringUntil('\n'); // Not sure, is this splitting the strings up to read them??
if (string1.substring(0, 2) == "LV") { // If string starts with LV...
int varpos = string1.indexOf(":", 3); // Move to the 3rd item in the string?
int varindex = atoi(string1.substring(3, varpos).c_str()); // Convert string to integer (i think)
float varstate = atof(string1.substring(varpos + 1).c_str()); // Converts integer to float value
varlist[varindex] = varstate; // adds the float value to the correct varlist item?
}
if (string1.substring(0, 2) == "SV") { // If substring starts with SV, read it
int varpos = string1.indexOf(":", 3);
int varindex = atoi(string1.substring(3, varpos).c_str());
float varstate = atof(string1.substring(varpos + 1).c_str());
if (varindex == 0) { // turning onboard led on and off... not sure why, it just stays on.
if (varstate == 1) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
}
}
}
void sendtrig(int index, float var) { // When button pressed, send the string
Serial.print("TV:" + String(index) + ":" + String(var)); // I think this is the bit sending the data as a string
}
void sendvar(int index, float var) {
Serial.print("LV:" + String(index) + ":" + String(var));
}
void sendfloatauto() {
float temp = analogRead(A0); // Read potentiometer on A0
temp = temp / 1024;
temp = min(temp, 0.99);
if (abs(temp - floatroz) > 0.05) {
floatroz = temp;
sendvar(10, temp); // Send heater fan speed knob position data to Omsi
}
}