Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect two SIMHUB devices using I2C. #43

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
50c0276
Added I2C sending as serial
Mar 17, 2024
9017277
Added main byppass to serial function, As example only buttonStatusCh…
Mar 17, 2024
b1ef413
Updated Approach. Uses I2CTransport.h which uses the I2CSerialBridge …
Mar 20, 2024
cac8fcd
Enabling slave bypass to serial and refactoring the I2C Transport layer.
Mar 20, 2024
f30fa92
Moved I2C FILES to libs.
Mar 21, 2024
99a49f8
Added serial interceptor, later will change class naming. This is the…
Mar 21, 2024
94bcfc4
Generalize to Streams.
Mar 21, 2024
c49feb3
Renamed I2C Classess and files
Mar 21, 2024
609e752
Slave impl not tested yet. The idea behind is that de StreamWrite mac…
Mar 21, 2024
df21309
Added new logic to send via serial de axis changed state with a callback
Mar 21, 2024
926f500
Active shAxisCallBack execution
Mar 21, 2024
e12d190
Analog Joystick support sending via customPacket 0x13
Mar 21, 2024
ca8d76f
Analog Axis implementation and analog axis simulation
Mar 22, 2024
08c7cd5
Merge pull request #1 from eCrowneEng/main
wapophis Mar 30, 2024
f0496c5
Merge pull request #2 from eCrowneEng/main
wapophis Mar 30, 2024
71ef04f
Settled high button count
Mar 31, 2024
e4e7f75
Added buttons types, 0 is a physycall button, 0 is a serialed button
Mar 31, 2024
3da22d3
Fixed build, sending at least two buttons.
Apr 1, 2024
6cca584
wip testing
Apr 2, 2024
e423a8c
UPDATED BUTONSTATUS_CHANGED
Apr 9, 2024
bd23f16
BUTTONMATRIXSTATUDCHANGED UPDATED TO SEND VIA ARQSERIAL WHEN I2C_BYPA…
Apr 9, 2024
d96bb73
synced with AVR-SIMHUB
Apr 14, 2024
be94ac8
MINOR FIXES
Apr 19, 2024
d4386ea
updated protocol decoder from avr-simhub
Apr 19, 2024
899fa4b
rebased I2CSerialBrdige module and ADDED SHVIRTUALROTARY
Apr 19, 2024
6ae38be
rebase SHRotaryEncoder from AVR-SIMHUB
Apr 19, 2024
468d57a
working in master mode encoders via i2c
Apr 20, 2024
010d959
Merge branch 'main' of https://github.com/eCrowneEng/ESP-SimHub
Apr 20, 2024
9196fe8
Merge pull request #3 from wapophis/i2c_encoders
wapophis Apr 20, 2024
dcf1049
Merge branch 'main' of https://github.com/wapophis/ESP-SimHub
Apr 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions src/ArqSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

#ifndef StreamRead
#define StreamRead Serial.read
#define StreamFlush Serial.flush
#define StreamWrite Serial.write
#define StreamPrint Serial.print
#define StreamFlush Serial1.flush
#define StreamWrite Serial1.write
#define StreamPrint Serial1.print
#define StreamAvailable Serial.available
#endif

Expand Down Expand Up @@ -39,6 +39,7 @@ class ARQSerial
do {
if (idleFunction != 0) idleFunction(true);
c = StreamRead();

if (c >= 0) {
#ifdef TESTFAIL
testfailidx = (testfailidx + 1) % 5000;
Expand All @@ -61,6 +62,7 @@ class ARQSerial
while (StreamAvailable() > 0) {
header = Arq_TimedRead();
//DebugPrintLn("hello1");

currentCrc = 0;

if (header == 0x01) {
Expand Down Expand Up @@ -146,6 +148,7 @@ class ARQSerial
StreamWrite(0x03);
StreamWrite(packetId);
StreamFlush();
Serial.printf("\nSendAcq[start,packetId]: [0x03,%d,%d]",packetId);
}

void SendNAcq(uint8_t lastKnownValidPacket, byte reason)
Expand All @@ -154,6 +157,7 @@ class ARQSerial
StreamWrite(lastKnownValidPacket);
StreamWrite(reason);
StreamFlush();
Serial.printf("\nSendNAcq[start,lastKnownValidPacket,reason]: [0x04,%d,%d]",lastKnownValidPacket,reason);
}

public:
Expand All @@ -166,15 +170,33 @@ class ARQSerial
StreamWrite(0x09);
StreamWrite(packetType);
StreamWrite(length);
Serial.printf("\nCustomPacketStart[start,packetType,length]: [0x09,%d,%d]",packetType,length);
}

void I2CustomPacketStart(byte packetType, uint8_t length) {
Wire.write(0x09);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the whole point of StreamWrite is to be able to replace it with whatever you need (in this case Wire.write), so that you don't have to add much custom code here :)

This comment was marked as resolved.

This comment was marked as resolved.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix at b1ef413

Wire.write(packetType);
Wire.write(length);
Serial.printf("\nI2CustomPacketStart[start,packetType,length]: [0x09,%d,%d]",packetType,length);
}

void CustomPacketSendByte(byte data) {
StreamWrite(data);
Serial.printf("\nCustomPacketSendByte[data]: [%d]",data);
}

void I2CustomPacketSendByte(byte data) {
Wire.write(data);
Serial.printf("\nI2CustomPacketSendByte[data]: [%d]",data);
}


void CustomPacketEnd() {
//Serial.write(0x00);
}
void I2CustomPacketEnd() {
//Serial.write(0x00);
}

int read() {
unsigned long fsr_startMillis = millis();
Expand All @@ -184,6 +206,7 @@ class ARQSerial
if (DataBuffer.size() > 0) {
uint8_t res = 0;
DataBuffer.pop(res);
Serial1.printf("\nread[data]: [%d]",res);
return (int)res;
}

Expand All @@ -195,8 +218,10 @@ class ARQSerial
}

int Available() {
//Serial1.printf("\nChecking Available darta\n");
if (idleFunction != 0) idleFunction(false);
if (DataBuffer.size() == 0) {

ProcessIncomingData();
}
return DataBuffer.size();
Expand All @@ -206,6 +231,7 @@ class ARQSerial
StreamWrite(0x08);
StreamWrite(data);
StreamFlush();
Serial1.printf("\nWrite[start,data]: [0x08,%d]",data);
}

void Print(char data)
Expand Down
147 changes: 137 additions & 10 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <Arduino.h>
#include <EspSimHub.h>
#include <Wire.h>

// No longer have to define whether it's an ESP32 or ESP8266, just do an initial compilation and
// VSCode will pick up the right environment from platformio.ini
Expand All @@ -8,6 +9,14 @@
// Less secure if you plan to commit or share your files, but saves a bunch of memory.
// If you hardcode credentials the device will only work in your network
#define USE_HARDCODED_CREDENTIALS false
#define IC2_SERIAL_BYPASS true

#if IC2_SERIAL_BYPASS
#define WIRE Wire
#define IC2_MASTER true
#define IC2_SLAVE false
#define IC2_ADDRESS 0x08
#endif

#if INCLUDE_WIFI
#if USE_HARDCODED_CREDENTIALS
Expand All @@ -34,7 +43,7 @@ FullLoopbackStream incomingStream;
//#define INCLUDE_RGB_LEDS_NEOPIXELBUS // use this instead of INCLUDE_WS2812B
//#define INCLUDE_WS2812B // consider using INCLUDE_RGB_LEDS_NEOPIXELBUS {"Name":"INCLUDE_WS2812B","Type":"autodefine","Condition":"[WS2812B_RGBLEDCOUNT]>0"}
//#define INCLUDE_WS2812B_MATRIX // consider using INCLUDE_WS2812B_MATRIX {"Name":"INCLUDE_WS2812B_MATRIX","Type":"autodefine","Condition":"[WS2812B_MATRIX_ENABLED]>0"}
//#define INCLUDE_BUTTONS //{"Name":"INCLUDE_BUTTONS","Type":"autodefine","Condition":"[ENABLED_BUTTONS_COUNT]>0","IsInput":true}
#define INCLUDE_BUTTONS //{"Name":"INCLUDE_BUTTONS","Type":"autodefine","Condition":"[ENABLED_BUTTONS_COUNT]>0","IsInput":true}
//#define INCLUDE_BUTTONMATRIX //{"Name":"INCLUDE_BUTTONMATRIX","Type":"autodefine","Condition":"[ENABLED_BUTTONMATRIX]>0","IsInput":true}
//#define INCLUDE_TM1637 //{"Name":"INCLUDE_TM1637","Type":"autodefine","Condition":"[TM1637_ENABLEDMODULES]>0"}
//#define INCLUDE_TM1638 //{"Name":"INCLUDE_TM1638","Type":"autodefine","Condition":"[TM1638_ENABLEDMODULES]>0"}
Expand Down Expand Up @@ -543,10 +552,10 @@ SHGamepadAxis SHGAMEPADAXIS03(GAMEPAD_AXIS_03_PIN, 2, GAMEPAD_AXIS_03_MINVALUE,
// ----------------------- ADDITIONAL BUTTONS ---------------------------------------------------------------
// https://github.com/zegreatclan/SimHub/wiki/Arduino-Press-Buttons
// ----------------------------------------------------------------------------------------------------------
#define ENABLED_BUTTONS_COUNT 0 //{"Group":"Additional Buttons","Name":"ENABLED_BUTTONS_COUNT","Title":"Additional buttons (directly connected to the arduino, 12 max) buttons count","DefaultValue":"0","Type":"int","Max":12}
#define ENABLED_BUTTONS_COUNT 1 //{"Group":"Additional Buttons","Name":"ENABLED_BUTTONS_COUNT","Title":"Additional buttons (directly connected to the arduino, 12 max) buttons count","DefaultValue":"0","Type":"int","Max":12}
#ifdef INCLUDE_BUTTONS

#define BUTTON_PIN_1 3 //{"Name":"BUTTON_PIN_1","Title":"1'st Additional button digital pin","DefaultValue":"3","Type":"pin;Button 1","Condition":"ENABLED_BUTTONS_COUNT>=1"}
#define BUTTON_PIN_1 D3 //{"Name":"BUTTON_PIN_1","Title":"1'st Additional button digital pin","DefaultValue":"3","Type":"pin;Button 1","Condition":"ENABLED_BUTTONS_COUNT>=1"}
#define BUTTON_WIRINGMODE_1 0 //{"Name":"BUTTON_WIRINGMODE_1","Title":"1'st Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=1","ListValues":"0,Pin to GND;1,VCC to pin"}
#define BUTTON_LOGICMODE_1 0 //{"Name":"BUTTON_LOGICMODE_1","Title":"1'st Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=1","ListValues":"0,Normal;1,Reversed"}

Expand Down Expand Up @@ -991,6 +1000,7 @@ unsigned long lastMatrixRefresh = 0;


void idle(bool critical) {
//Serial.printf("\n [%d] Ejecutando la función idle %d",millis(),critical);
#if INCLUDE_WIFI
yield();
ECrowneWifi::flush();
Expand Down Expand Up @@ -1082,16 +1092,49 @@ void EncoderPositionChanged(int encoderId, int position, byte direction) {
#endif
}
#endif
uint8_t endWireTransmission(bool stop){
uint8_t error=Wire.endTransmission(stop);
if(error=0){
Serial.printf("\n Correct wire close \n");
}
if(error==1){
Serial.printf("\n Wire buffer exausted \n");
}
if(error==2){
Serial.printf("\n received NACK on transmit of address.\n");
}
if(error==3){
Serial.printf("received NACK on transmit of data.");
}
if(error==4){
Serial.printf(" other error.");
}
if(error==5){
Serial.printf("timeout");
}
Serial.flush();
return error;

}
void buttonStatusChanged(int buttonId, byte Status) {
#ifdef INCLUDE_GAMEPAD
Joystick.setButton(TM1638_ENABLEDMODULES * 8 + buttonId - 1, Status);
Joystick.sendState();
#else
arqserial.CustomPacketStart(0x03, 2);
arqserial.CustomPacketSendByte(buttonId);
arqserial.CustomPacketSendByte(Status);
arqserial.CustomPacketEnd();
#if IC2_SERIAL_BYPASS
Wire.beginTransmission(0x08); /* begin with device address 8 */
arqserial.I2CustomPacketStart(0x03,2);
arqserial.I2CustomPacketSendByte(buttonId);
arqserial.I2CustomPacketSendByte(Status);
arqserial.I2CustomPacketEnd();
endWireTransmission(true);
#else
arqserial.CustomPacketStart(0x03,2);
arqserial.CustomPacketSendByte(buttonId);
arqserial.CustomPacketSendByte(Status);
arqserial.CustomPacketEnd();
#endif

#endif
}

Expand All @@ -1109,6 +1152,76 @@ void buttonMatrixStatusChanged(int buttonId, byte Status) {
}
#endif


void resendToSerialFromMasterDevice(size_t howManyChars){
// FlowSerialDebugPrintLn("Received data");
//int recvBytes=0;

// int buttonId=-1;
//byte buttonStatus=0;

while (0 <Wire.available()) {
char c = Wire.read(); /* receive byte as a character */
// if(recvBytes==3){
// buttonId=c;
// }
// if(recvBytes==4){
// buttonStatus=c;
// }
// recvBytes++;
// Serial.write(c);
// Serial.flush();
// Serial.print(c); /* print the character */
FlowSerialWrite(c);
}
// buttonStatusChanged(buttonId,buttonStatus);
//Serial.println(); /* to newline */
}


bool isSlaveAvailable(){
Wire.beginTransmission(IC2_ADDRESS);
uint8_t error = endWireTransmission(true);

if(error==0){
Serial.printf("\n Slave device detected at address 8\n");
return true;
}
return false;
}

/** SETUP SERIAL BYPASS IC2 MASTER, USE WHEN THIS DEVICE COMMAND THE SENDING WORKFLOW*/
void ic2SetupMaster(){
WIRE.begin();
while(!isSlaveAvailable()){
Serial.printf("\n Slave device not available, retrying 1 sec later");
delay(1000);
};
}

/** SETUP SERIAL BYPASS IC2 SLAVE, USE WHEN THIS DEVICE IS CONNECTED TO SIMHUB*/
void ic2SetupSlave(){
Wire.begin(IC2_ADDRESS);
Wire.onReceive(resendToSerialFromMasterDevice); /* register receive event */
}


void ic2SetupSerialBypass(){
#if IC2_MASTER
ic2SetupMaster();
#endif
#if IC2_SLAVE
ic2SetupSlave();
#endif

}



/*****
*
* SETUP DEVICES ENABLED
*/
void setup()
{
#if INCLUDE_WIFI
Expand Down Expand Up @@ -1236,7 +1349,7 @@ void setup()
shMatrixHT16H33SingleColor.begin(ADA_HT16K33_SINGLECOLORMATRIX_I2CADDRESS);
#endif

#ifdef INCLUDE_OLED
#ifdef INCLUDE_OLEDPus
shGLCD.Init();
#endif

Expand Down Expand Up @@ -1293,6 +1406,14 @@ void setup()

shCustomProtocol.setup();
arqserial.setIdleFunction(idle);
Serial.begin(115200);
delay(200);
Serial.printf("Configurado el serial1 del slave");

#if IC2_SERIAL_BYPASS
ic2SetupSerialBypass();

#endif

#if(GAMEPAD_AXIS_01_ENABLED == 1)
SHGAMEPADAXIS01.SetJoystick(&Joystick);
Expand Down Expand Up @@ -1369,7 +1490,10 @@ char loop_opt;
char xactionc;
unsigned long lastSerialActivity = 0;


/****
*
* MAIN LOOP
*/
void loop() {
#if INCLUDE_WIFI
ECrowneWifi::loop();
Expand Down Expand Up @@ -1400,6 +1524,8 @@ void loop() {
UpdateGamepadState();
#endif
shCustomProtocol.loop();
//delay(1000);
//Serial.printf("\nI'm alive\n");

// Wait for data
if (FlowSerialAvailable() > 0) {
Expand All @@ -1408,7 +1534,7 @@ void loop() {
lastSerialActivity = millis();
// Read command
loop_opt = FlowSerialTimedRead();

switch(loop_opt) {
case '1': Command_Hello(); break;
case '8': Command_SetBaudrate(); break;
Expand Down Expand Up @@ -1450,3 +1576,4 @@ void loop() {
Command_Shutdown();
}
}