diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..17659d6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,37 @@ +{ + "files.associations": { + "array": "cpp", + "string": "cpp", + "string_view": "cpp", + "ranges": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "initializer_list": "cpp", + "regex": "cpp", + "*.tcc": "cpp", + "optional": "cpp", + "istream": "cpp", + "ostream": "cpp", + "system_error": "cpp", + "functional": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "bitset": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "typeinfo": "cpp", + "random": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "set": "cpp", + "cstddef": "cpp" + }, + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/lib/AnalogAxisSimulator/AnalogAxis.cpp b/lib/AnalogAxisSimulator/AnalogAxis.cpp new file mode 100644 index 0000000..181744f --- /dev/null +++ b/lib/AnalogAxisSimulator/AnalogAxis.cpp @@ -0,0 +1,54 @@ +#include "AnalogAxis.h" + +int pot = -1; +bool AnalogAxisSimulator::read(int samplingRate){ + + + if(millis()-lastGeneratedReading>300){ + pot=analogReadXXbit(samplingRate); + lastGeneratedReading=millis(); + } + + if (lastAxisValue != pot) { + Serial.println("\nAnalogAxisSimulator::setAnalogReading"); + Serial.println(pot); + lastAxisValue = pot; + + int mapped = map(pot, minimumInputValue, maximumInputValue, 0, 1024); + Serial.print("\nMapped:"); + Serial.print(mapped); + float mapped2 = min((float)1, max((float)0,(float) ((float)mapped / (float)1024))); + Serial.print("\nMapped2:"); + Serial.print(mapped2); + + if (exponentialFactor != 1) { + mapped2 = pow(mapped2, 1.0 / (float)exponentialFactor); + } + + mapped2 = mapped2 * 1024; + Serial.print("\nMapped2 Powed:"); + Serial.print(mapped2); + if(this->shAxisChangedCallback!=nullptr){ + Serial.println("\nCallback defined"); + shAxisChangedCallback(axisIdx,mapped2); + } + } + return false; + +} + + float AnalogAxisSimulator::analogReadXXbit(byte bits_of_precision) + { + uint8_t n = bits_of_precision - 10; + unsigned long oversample_num = 1 << (2 * n); + uint8_t divisor = 1 << n; + unsigned long reading_sum = 0; + unsigned long inner_sum = 0; + for (unsigned long j = 0; j < oversample_num; j++) + { + inner_sum +=random(-1024,1024); + } + unsigned int reading = (inner_sum + (unsigned long)divisor / 2UL) >> n; + reading_sum += reading; + return (float)reading_sum; + } \ No newline at end of file diff --git a/lib/AnalogAxisSimulator/AnalogAxis.h b/lib/AnalogAxisSimulator/AnalogAxis.h new file mode 100644 index 0000000..034d3ce --- /dev/null +++ b/lib/AnalogAxisSimulator/AnalogAxis.h @@ -0,0 +1,25 @@ +#include +typedef void(*SHAxisChanged) (int, int); + +class AnalogAxisSimulator{ + int axisIdx=1; + int lastAxisValue = -1; + int minimumInputValue=0; + int maximumInputValue=1024; + int samplingRate=10; + float exponentialFactor=1; + unsigned long lastGeneratedReading=millis(); + SHAxisChanged shAxisChangedCallback=nullptr; + public: + + AnalogAxisSimulator(int axisIdx){ + this->axisIdx=axisIdx; + } + bool read(int samplingRate); + + void setCallBack(SHAxisChanged callback){ + shAxisChangedCallback=callback; + } + + float analogReadXXbit(byte bits_of_precision); +}; \ No newline at end of file diff --git a/lib/I2CSerialBridge/I2CManager.h b/lib/I2CSerialBridge/I2CManager.h new file mode 100644 index 0000000..b94e646 --- /dev/null +++ b/lib/I2CSerialBridge/I2CManager.h @@ -0,0 +1,69 @@ +#pragma once +#include "I2CTransportMaster.h" +#include "I2CTransportSlave.h" + +/*** + * "This Manager is responsible for configuring the behavior based on the master-slave role for I2C communication." +*/ +class I2CTransportManager { + public: + #if I2C_BYPASS_MASTER + static I2CTransportMaster tm; + #endif + static I2CTransportSlave ts; + + static void setup(FullLoopbackStream *outgoingStream){ + #if I2C_BYPASS_MASTER + #if I2C_SERIAL_BYPASS_DEBUG + Serial.print("\nSetup as Master\n"); + Serial.flush(); + #endif + tm.setup(outgoingStream); + #endif + + #if I2C_BYPASS_SLAVE + Serial.print("Setup as Slave"); + Serial.flush(); + ts.setup(outgoingStream); + #endif + } + static void loop(){ + #if I2C_BYPASS_MASTER + tm.loop(); + #endif + + #if I2C_BYPASS_SLAVE + ts.loop(); + #endif + } + + static void flush(){ + #if I2C_BYPASS_MASTER + tm.flush(); + #endif + + #if I2C_BYPASS_SLAVE + ts.flush(); + #endif + } +}; + +#if I2C_BYPASS_MASTER +#define StreamRead outgoingStream.read +#define StreamAvailable outgoingStream.available +#define FlowSerialFlush Serial.flush +#define StreamFlush I2CTransportManager::flush +#define StreamWrite outgoingStream.write +//#define StreamWrite WIRE.write +#define StreamPrint outgoingStream.print +/** SETUP SERIAL BYPASS I2C SLAVE, USE WHEN THIS DEVICE IS CONNECTED TO SIMHUB*/ +#define FlowSerialBegin [](unsigned long baud) { Serial.print("Hola mundo");} +#endif + #if I2C_BYPASS_SLAVE + #define StreamRead Serial.read + #define StreamFlush Serial.flush + #define StreamWrite Serial.write + #define StreamPrint Serial.print + #define StreamAvailable Serial.available + #define FlowSerialBegin [](unsigned long baud) { Serial.begin(baud);} + #endif \ No newline at end of file diff --git a/lib/I2CSerialBridge/I2CSerialBridge.h b/lib/I2CSerialBridge/I2CSerialBridge.h new file mode 100644 index 0000000..6279f4d --- /dev/null +++ b/lib/I2CSerialBridge/I2CSerialBridge.h @@ -0,0 +1,149 @@ + +#include +#include + +#ifndef WIRE +#error WIRE must be settled to have a correct custom wire config in your MASTER config. +#endif + +class I2CSerialBridge{ + FullLoopbackStream *outgoingStream; + uint8_t address; + public: + + I2CSerialBridge(uint8_t address) { + this->address=address; + // CONFIG AS MASTER OR SLAVE WITH ADDRESS + } + + void setup(FullLoopbackStream *outgoingStream){ + this->outgoingStream = outgoingStream; + } + + void loop() { + #if I2C_SERIAL_BYPASS_DEBUG + // Serial.print("\n I2CSerialBridge - loop"); + // Serial.flush(); + #endif + // put your main code here, to run repeatedly + check_status(); + this->flush(); + } + + void flush() { + // if there is data available in the stream, it's meant + // to go from Serial port to the slave + size_t availableLength = this->outgoingStream->available(); + if (availableLength) + { + #if I2C_SERIAL_BYPASS_DEBUG + Serial.println("\n I2CSerialBridge - flush"); + Serial.print("\nflushing with this much data:"); + Serial.print(availableLength); + #endif + + + // read the available data from the stream, and put in in the buffer + char sbuf[availableLength]; + this->outgoingStream->readBytes(sbuf, availableLength); + + // send data to client + WIRE.beginTransmission(address); + size_t total = WIRE.write(sbuf, availableLength); + WIRE.endTransmission(); + //endWireTransmission(false); + // DEBUG OUTPUT STREAM + for (int i=0;i data sent to client %s: %d bytes \n", I2C_ADDRESS, total); + // Serial.printf("%d %d\n",sbuf[0], sbuf[1]); + #endif + } + } + + + /** SETUP SERIAL BYPASS I2C MASTER, USE WHEN THIS DEVICE COMMAND THE SENDING WORKFLOW*/ + void i2cSetupMaster(){ + #if I2C_SERIAL_BYPASS_DEBUG + Serial.print("WIRE.BEGIN(), initializing...."); + #endif + WIRE.begin(); + #if I2C_SERIAL_BYPASS_DEBUG + Serial.print("WIRE CONFIGURING TIMEOUT 300 ms .... "); + #endif + WIRE.setTimeout(300); + + while(!isSlaveAvailable()){ + #if I2C_SERIAL_BYPASS_DEBUG + Serial.print("\n Slave device not available, retrying 1 sec later"); + #endif + delay(1000); + }; + } + + private: + /** TODO CONTROL THAT TRANSPORT LAYER IS READY AND CONNECTED*/ + void check_status(){ + #if I2C_SERIAL_BYPASS_DEBUG + // Serial.println("\n I2CSerialBridge - check_status"); + // Serial.flush(); + #endif + } + + + + +uint8_t endWireTransmission(bool stop){ + uint8_t error=WIRE.endTransmission(stop); + if(error==0){ + Serial.print("\n Correct wire close \n"); + } + if(error==1){ + Serial.print("\n Wire buffer exausted \n"); + } + if(error==2){ + Serial.print("\n received NACK on transmit of address.\n"); + } + if(error==3){ + Serial.print("received NACK on transmit of data."); + } + if(error==4){ + Serial.print(" other error."); + } + if(error==5){ + Serial.print("timeout"); + } + Serial.print("\n Error code is "); + Serial.print(error); + Serial.println(); + Serial.flush(); + return error; + +} + +bool isSlaveAvailable(){ + #if I2C_SERIAL_BYPASS_DEBUG + Serial.print("\n Testing slave availability -> Beging transmission to "); + Serial.print(I2C_ADDRESS); + Serial.println("\n"); + #endif + WIRE.beginTransmission(I2C_ADDRESS); + uint8_t error = endWireTransmission(true); + + if(error==0){ + Serial.print("\n Slave device detected at address "); + Serial.print(I2C_ADDRESS); + Serial.print("\n"); + return true; + } + return false; +} + + +}; \ No newline at end of file diff --git a/lib/I2CSerialBridge/I2CTransport.h b/lib/I2CSerialBridge/I2CTransport.h new file mode 100644 index 0000000..12016b8 --- /dev/null +++ b/lib/I2CSerialBridge/I2CTransport.h @@ -0,0 +1,12 @@ +#pragma once +#include + +#include + +class I2CTransport { + public: + I2CTransport(){} + virtual void loop() = 0 ; + virtual void flush() = 0; + virtual void setup(Stream *) = 0; +}; \ No newline at end of file diff --git a/lib/I2CSerialBridge/I2CTransportMaster.h b/lib/I2CSerialBridge/I2CTransportMaster.h new file mode 100644 index 0000000..776b10a --- /dev/null +++ b/lib/I2CSerialBridge/I2CTransportMaster.h @@ -0,0 +1,41 @@ + +#pragma once +#include "I2CTransport.h" +#include "I2CSerialBridge.h" + +#ifndef WIRE +#error WIRE must be settled to have a correct custom wire config in your MASTER config. +#endif + +#if I2C_BYPASS_MASTER +I2CSerialBridge instance(I2C_ADDRESS); + +class I2CTransportMaster : public I2CTransport { + public: + + I2CTransportMaster(){} + void setup(Stream *outgoingStream){ + i2cSetupSerialBypass(); + instance.setup((FullLoopbackStream*) outgoingStream); + } + void loop() { + instance.loop(); + } + void flush() { + instance.flush(); + } + + + void i2cSetupSerialBypass(){ + #if I2C_SERIAL_BYPASS_DEBUG + Serial.print("\n Setting up the master slave connection with slave at "); + Serial.print(I2C_ADDRESS); + Serial.println("\n"); + #endif + #if I2C_BYPASS_MASTER + instance.i2cSetupMaster(); + #endif + + } +}; +#endif \ No newline at end of file diff --git a/lib/I2CSerialBridge/I2CTransportSlave.h b/lib/I2CSerialBridge/I2CTransportSlave.h new file mode 100644 index 0000000..3a1661e --- /dev/null +++ b/lib/I2CSerialBridge/I2CTransportSlave.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include "I2CTransport.h" + +#define StreamWrite + +#ifndef WIRE +#error WIRE must be settled to have a correct custom wire config in your SLAVE config. +#endif + +#ifndef I2C_ADDRESS +#error I2C_ADDRESS must be settled to have a correct custom wire config in your SLAVE config. +#endif + +class I2CTransportSlave : public I2CTransport { + static Stream *outgoingStream; + public: + void setup(Stream *outgoingStream){ + this->outgoingStream=outgoingStream; + ic2SetupSlave(); + } + + void loop() { + + } + void flush() { + + } + + static void resendToSerialFromDevice(size_t howManyChars){ + byte bffer[Wire.available()]; + int bfferIdx=0; + while (0 +#include + +class SHRotaryEncoderContext { +private: + byte direction[8]; + int position[8]; + unsigned long positionLastChanged[8]; + bool buttonPressed[8]; + + +public: + void init(){ + + } + + void updateContext(int encoderId, int pos, byte dir){ + // char sbuf[150]; + // sprintf(sbuf,"\nSHRotaryEncoderContext::updateContext(%d,%d,%d);\n",encoderId,pos,dir); + // Serial.print(sbuf); + if(dir==0xD7){ + this->buttonPressed[encoderId-1]=pos == 1? 0 : 1; + Serial.print(this->buttonPressed[encoderId-1]); + }else{ + this->direction[encoderId-1]=dir; + this->position[encoderId-1]=pos; + this->positionLastChanged[encoderId-1]=millis(); + } + + // sprintf(sbuf,"\nSHRotaryEncoderContext::updateContext::direction:%d",this->direction[encoderId-1]); + // Serial.print(sbuf); + // sprintf(sbuf,"\nSHRotaryEncoderContext::updateContext::position:%d",this->position[encoderId-1]); + // Serial.print(sbuf); + // sprintf(sbuf,"\nSHRotaryEncoderContext::updateContext::positionLastChanged:%lu",this->positionLastChanged[encoderId-1]); + // Serial.print(sbuf); + // Serial.println(""); + + } + + int getPosition(int encoderId){ + return this->position[encoderId-1]; + } + + byte getDirection(int encoderId){ + return this->direction[encoderId-1]; + } + + unsigned long getPositionLastChanged(int encoderId){ + return this->positionLastChanged[encoderId-1]; + } + + bool getButtonState(int encoderId){ + return this->buttonPressed[encoderId-1]; + } + + void logDirection(){ + char sbuf[150]; + for(int i=0;i<8;i++){ + sprintf(sbuf+strlen(sbuf)," %d,",this->direction[i]); + } + // Serial.print("\nSHRotaryEncoderContext::direction: "); + Serial.print(sbuf); + Serial.println(""); + + } + + void logPosition(){ + char sbuf[150]; + for(int i=0;i<8;i++){ + sprintf(sbuf+strlen(sbuf)," %d,",this->position[i]); + } + // Serial.print("\nSHRotaryEncoderContext::position: "); + Serial.print(sbuf); + Serial.println(""); + } + +}; \ No newline at end of file diff --git a/lib/SHRotaryEncondersContext/SHVirtualRotaryEncoder.h b/lib/SHRotaryEncondersContext/SHVirtualRotaryEncoder.h new file mode 100644 index 0000000..d422015 --- /dev/null +++ b/lib/SHRotaryEncondersContext/SHVirtualRotaryEncoder.h @@ -0,0 +1,87 @@ +#pragma once +#ifndef __SHVIRTUALROTARYENCODER_H__ +#define __SHVIRTUALROTARYENCODER_H__ + +#include +#include +#include +#include + +class SHVirtualRotaryEncoder : public SHRotaryEncoder { +private: + SHRotaryEncoderContext* context; + +public: + + SHVirtualRotaryEncoder(SHRotaryEncoderContext* context){ + this->context=context; + } + + void begin(uint8_t outputAPin, uint8_t outputBPin, int buttonPin, bool reverse, bool enablePullup, byte encoderid, bool half, SHRotaryEncoderPositionChanged changedcallback) override{ + this->id=encoderid; + this->inputLastState = 0; + this->buttonLastState = enablePullup? HIGH: LOW; + this->halfSteps=half; + this->positionChangedCallback=changedcallback; + context->updateContext(id,0,255); + } + + uint8_t getDirection(uint8_t delay, unsigned long referenceTime) override{ + // Serial.print(" DirecionLastCHange:"); + // Serial.print(this->context->getDirection(this->id)); + // Serial.print(" | "); + // Serial.print(" ReferenceTime:"); + // Serial.print(referenceTime); + // Serial.print(" | "); + // Serial.print(" getPositionLastChanged:"); + // Serial.print(context->getPositionLastChanged(this->id)); + // Serial.print(" | "); + // Serial.print(" Diff:"); + // Serial.print(referenceTime - context->getPositionLastChanged(this->id)); + // Serial.print(" | \n"); + + if (directionLastChange != 255 && (referenceTime - context->getPositionLastChanged(this->id)) < delay) { + // this->context->updateContext(this->id,counter,directionLastChange); + return directionLastChange; + } + // this->context->updateContext(this->id,counter,255); + return 255; + } + + uint8_t getPressed() override{ + return !buttonLastState; + } + + void read() override{ + + this->direction=this->context->getDirection(this->id); + this->counter=this->context->getPosition(this->id); + + // Serial.print(" SHVirtualRotaryEncoder::read:direction:"); + // Serial.print(this->context->getDirection(this->id)); + // Serial.print(" \n"); + + if (direction == 0) { + counter++; + positionChangedCallback(id, counter, direction); + //positionLastChanged = millis(); + directionLastChange = 0; + } + else if (direction == 1) { + counter--; + positionChangedCallback(id, counter, direction); + //positionLastChanged = millis(); + directionLastChange = 1; + } + + this->buttonLastState=context->getButtonState(id); + + //SHRotaryEncoder::read(); + } + + + +}; + + +#endif \ No newline at end of file diff --git a/lib/SimHubProtocolDecoder/SimHubProtocolDecoder.cpp b/lib/SimHubProtocolDecoder/SimHubProtocolDecoder.cpp new file mode 100644 index 0000000..e69de29 diff --git a/lib/SimHubProtocolDecoder/SimHubProtocolDecoder.h b/lib/SimHubProtocolDecoder/SimHubProtocolDecoder.h new file mode 100644 index 0000000..eb2ab07 --- /dev/null +++ b/lib/SimHubProtocolDecoder/SimHubProtocolDecoder.h @@ -0,0 +1,116 @@ +#include + + +typedef void(*SHButtonChangedEventCallBack) (int, byte); //function pointer prototype +typedef void(*SHRotaryEncoderPositionChangedEventCallBack) (int, int, byte); //function pointer prototype +/*** + * | PACKET HEADER | SIZE | DSCRIPTION | + * | 0x01 | 3 | ENCODER SIZE 3 + * | 0X02 | 2 | ENCODER SIZE 2 + * | 0X03 | 2 | BUTTON STATE SIZE 2 + * | 0X04 | 3 | TM1638 BUTTONS STATE SIZE 3 + * +*/ +byte packetsHeaders[]={0x01,0x02,0x03,0x04}; +byte packetsPayloadLength[]={3,2,2,3}; + +class EventCallBackManager{ + SHButtonChangedEventCallBack shButtonChangedCallback; + SHRotaryEncoderPositionChangedEventCallBack SHRotaryEncoderPositionChangedCallback; + + public: + void setButtonCallBack(SHButtonChangedEventCallBack callback){ + shButtonChangedCallback=callback; + } + SHButtonChangedEventCallBack getButtonCallback(){ + return shButtonChangedCallback; + } + + void setEncoderPositionChangedCallback(SHRotaryEncoderPositionChangedEventCallBack callback){ + SHRotaryEncoderPositionChangedCallback=callback; + } + SHRotaryEncoderPositionChangedEventCallBack getEncoderPositionChangedCallback(){ + return SHRotaryEncoderPositionChangedCallback; + } +}; + + +static void decodeBuffer(EventCallBackManager *callbacker,Stream *stream){ + byte packetType=0x0; + int size=-1; + //TODO: REMOVE IS FOR TESTING + // while(stream->available()){ + // Serial.write(stream->read()); + // } + // return; + #define IC2_SERIAL_BYPASS_DEBUG false + #if IC2_SERIAL_BYPASS_DEBUG + Serial.print("\n Disponible en buffer "); + Serial.print(stream->available()); + Serial.print("\n"); + Serial.flush(); + #endif + if(stream->available()){ + packetType=stream->read(); + #if IC2_SERIAL_BYPASS_DEBUG + Serial.print("\n Initial packetType "); + Serial.print(packetType); + Serial.print("\n"); + Serial.flush(); + #endif + } + + // CUSTOM PACKETS + if(packetType==0x09){ + packetType=stream->read(); + #if IC2_SERIAL_BYPASS_DEBUG + Serial.print("\n Accepted packetType "); + Serial.print(packetType); + Serial.print("\n"); + Serial.flush(); + #endif + + size=stream->read(); + + #if IC2_SERIAL_BYPASS_DEBUG + Serial.print("\n Payload Size is "); + Serial.print(size); + Serial.print("\n"); + Serial.flush(); + #endif + + if(packetType==0x01){ + int encoderId=stream->read(); + byte direction=stream->read(); + int position=stream->read(); + callbacker->getEncoderPositionChangedCallback()(encoderId,position,direction); + } + + if(packetType==0x02){ + int encoderId=stream->read(); + byte direction=stream->read(); + callbacker->getEncoderPositionChangedCallback()(encoderId,direction,0xD7); // 0XD7 Identify a button status changed + } + + if(packetType==0x03){ + int buttonId; + buttonId=stream->read(); + byte status; + status=stream->read(); + #if IC2_SERIAL_BYPASS_DEBUG + Serial.print("\n BUtton state changed "); + Serial.println(buttonId); + Serial.println(status); + Serial.flush(); + #endif + callbacker->getButtonCallback()(buttonId,status); + } + + while (0 available()){ + Serial.write(stream->read()); + } + stream->flush(); + + } + +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index ca78651..ac38593 100644 --- a/platformio.ini +++ b/platformio.ini @@ -58,9 +58,31 @@ build_flags = monitor_speed = 115200 ;upload_port = COM4 ;build_type = debug # set this to debug only for debugging, as it's slower. -monitor_filters = esp8266_exception_decoder +monitor_filters = esp8266_exception_decoder, default, debug build_unflags = -fno-rtti # comment this out if you need more ram, but you'll need to make some type assumptions +monitor_rts = 0 +monitor_dtr = 0 +[env:esp8266debug] +platform = espressif8266 +# this should be set to your flavor of esp8266, for instance d1_mini +# BOARD_LIST: https://docs.platformio.org/en/latest/boards/index.html#espressif-8266 +board = nodemcuv2 +framework = arduino +lib_deps = + ${common.lib_deps} + fastled/FastLED@3.4 #newer versions don't seem to work with esp8266 in my tests + # add any libraries that are specific for the es8266 + +build_flags = + -w -DESP8266=true +monitor_speed = 115200 +upload_port = COM3 +build_type = debug # set this to debug only for debugging, as it's slower. +monitor_filters = esp8266_exception_decoder, default +build_unflags = -fno-rtti # comment this out if you need more ram, but you'll need to make some type assumptions +monitor_rts = 0 +monitor_dtr = 0 ############################################# # ESP32 diff --git a/src/ArqSerial.h b/src/ArqSerial.h index 1523799..1681f6a 100644 --- a/src/ArqSerial.h +++ b/src/ArqSerial.h @@ -39,6 +39,7 @@ class ARQSerial do { if (idleFunction != 0) idleFunction(true); c = StreamRead(); + if (c >= 0) { #ifdef TESTFAIL testfailidx = (testfailidx + 1) % 5000; @@ -61,6 +62,7 @@ class ARQSerial while (StreamAvailable() > 0) { header = Arq_TimedRead(); //DebugPrintLn("hello1"); + currentCrc = 0; if (header == 0x01) { @@ -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) @@ -154,6 +157,7 @@ class ARQSerial StreamWrite(lastKnownValidPacket); StreamWrite(reason); StreamFlush(); + //Serial.printf("\nSendNAcq[start,lastKnownValidPacket,reason]: [0x04,%d,%d]",lastKnownValidPacket,reason); } public: @@ -166,15 +170,37 @@ class ARQSerial StreamWrite(0x09); StreamWrite(packetType); StreamWrite(length); + // Serial.write(0x09); + // Serial.write(packetType); + // Serial.write(length); + //Serial.printf("\nCustomPacketStart[start,packetType,length]: [0x09,%d,%d]",packetType,length); } + // void I2CustomPacketStart(byte packetType, uint8_t length) { + // Wire.write(0x09); + // Wire.write(packetType); + // Wire.write(length); + // Serial.printf("\nI2CustomPacketStart[start,packetType,length]: [0x09,%d,%d]",packetType,length); + // } + void CustomPacketSendByte(byte data) { StreamWrite(data); + Serial.write(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(); @@ -184,6 +210,7 @@ class ARQSerial if (DataBuffer.size() > 0) { uint8_t res = 0; DataBuffer.pop(res); + //Serial1.print("\nread[data]: [%d]",res); return (int)res; } @@ -195,8 +222,10 @@ class ARQSerial } int Available() { + //Serial1.printf("\nChecking Available darta\n"); if (idleFunction != 0) idleFunction(false); if (DataBuffer.size() == 0) { + ProcessIncomingData(); } return DataBuffer.size(); @@ -206,6 +235,7 @@ class ARQSerial StreamWrite(0x08); StreamWrite(data); StreamFlush(); + //Serial1.printf("\nWrite[start,data]: [0x08,%d]",data); } void Print(char data) diff --git a/src/SHGamepadAxis.h b/src/SHGamepadAxis.h index ee7989c..de92947 100644 --- a/src/SHGamepadAxis.h +++ b/src/SHGamepadAxis.h @@ -2,18 +2,22 @@ #define __SHGAMEPADAXIS_H__ #include -#include +/*#include */ + + +typedef void(*SHAxisChanged) (int, int); + class SHGamepadAxis { private: - + SHAxisChanged shAxisChangedCallback=nullptr; int lastAxisValue = -1; int axisPin = -1; int axisIdx = -1; int minimumInputValue; int maximumInputValue; int samplingRate; - Joystick_* joystick; + //Joystick_* joystick; float exponentialFactor; float analogReadXXbit(uint8_t analogPin, uint8_t bits_of_precision) { @@ -36,17 +40,17 @@ class SHGamepadAxis { switch (axisIdx) { case 0: - joystick->setThrottle(value); break; + // joystick->setThrottle(value); break; case 1: - joystick->setAccelerator(value); break; + //joystick->setAccelerator(value); break; case 2: - joystick->setBrake(value); break; + //joystick->setBrake(value); break; - default: + default: break; } - joystick->sendState(); + //joystick->sendState(); } public: @@ -60,19 +64,23 @@ class SHGamepadAxis { this->exponentialFactor = exponentialFactor; } - void SetJoystick(Joystick_* joystick) { - this->joystick = joystick; - read(); + void setCallBack(SHAxisChanged callback){ + this->shAxisChangedCallback=callback; } + // void SetJoystick(Joystick_* joystick) { + // this->joystick = joystick; + // read(); + // } + bool read() { int pot = analogReadXXbit(axisPin, samplingRate); - if (lastAxisValue != pot) { + if (lastAxisValue != pot) { lastAxisValue = pot; int mapped = map(pot, minimumInputValue, maximumInputValue, 0, 1024); - float mapped2 = min(1, max(0, (float)mapped / (float)1024)); + float mapped2 = min(1, max(0, (mapped / 1024))); if (exponentialFactor != 1) { mapped2 = pow(mapped2, 1.0 / (float)exponentialFactor); @@ -80,8 +88,32 @@ class SHGamepadAxis { mapped2 = mapped2 * 1024; setAxis(axisIdx, mapped2); + if(this->shAxisChangedCallback!=nullptr){ + shAxisChangedCallback(axisIdx,mapped2); + } } } + + bool setAxisAnalogReading(int pot) { + + if (lastAxisValue != pot) { + lastAxisValue = pot; + + int mapped = map(pot, minimumInputValue, maximumInputValue, 0, 1024); + float mapped2 = min(1, max(0, (mapped / 1024))); + + if (exponentialFactor != 1) { + mapped2 = pow(mapped2, 1.0 / (float)exponentialFactor); + } + + mapped2 = mapped2 * 1024; + setAxis(axisIdx, mapped2); + if(this->shAxisChangedCallback!=nullptr){ + shAxisChangedCallback(axisIdx,mapped2); + } + } + } + }; #endif \ No newline at end of file diff --git a/src/SHRotaryEncoder.h b/src/SHRotaryEncoder.h index 8da4ce6..af2456b 100644 --- a/src/SHRotaryEncoder.h +++ b/src/SHRotaryEncoder.h @@ -50,7 +50,7 @@ static const unsigned char halfStepsTable[][4] = typedef void(*SHRotaryEncoderPositionChanged) (int, int, byte); class SHRotaryEncoder { -private: +protected: FastDigitalPin outputA; // CLK FastDigitalPin outputB; // DT @@ -74,7 +74,7 @@ class SHRotaryEncoder { public: - void begin(uint8_t outputAPin, uint8_t outputBPin, int buttonPin, bool reverse, bool enablePullup, byte encoderid, bool half, SHRotaryEncoderPositionChanged changedcallback) { +virtual void begin(uint8_t outputAPin, uint8_t outputBPin, int buttonPin, bool reverse, bool enablePullup, byte encoderid, bool half, SHRotaryEncoderPositionChanged changedcallback) { halfSteps = half; buttonDebouncer.begin(50); outputA.begin((!reverse) ? outputAPin : outputBPin); @@ -93,19 +93,19 @@ class SHRotaryEncoder { buttonLastState = button.digitalRead(); positionChangedCallback = changedcallback; } - - uint8_t getDirection(uint8_t delay, unsigned long referenceTime) { + +virtual uint8_t getDirection(uint8_t delay, unsigned long referenceTime) { if (directionLastChange != 255 && (referenceTime - positionLastChanged) < delay) { return directionLastChange; } return 255; } - uint8_t getPressed() { +virtual uint8_t getPressed() { return button.isValid() && !buttonLastState; } - void read() { +virtual void read() { if (!halfSteps) inputLastState = fullStepsTable[inputLastState & 0xf][(outputB.digitalRead() << 1) | outputA.digitalRead()]; else { @@ -119,12 +119,14 @@ class SHRotaryEncoder { positionChangedCallback(id, counter, 0); positionLastChanged = millis(); directionLastChange = 0; + //Serial.print("DIR_CCW"); } else if (direction == DIR_CW) { counter--; positionChangedCallback(id, counter, 1); positionLastChanged = millis(); directionLastChange = 1; + //Serial.print("DIR_CW"); } if (button.isValid()) { diff --git a/src/main.cpp b/src/main.cpp index f704a13..299efcc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include #include + // 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 @@ -8,6 +9,20 @@ // 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 I2C_SERIAL_BYPASS true + +#if I2C_SERIAL_BYPASS + #define WIRE Wire + #define I2C_BYPASS_MASTER true + #define I2C_BYPASS_SLAVE false + #define I2C_ADDRESS 0x08 + #define I2C_SERIAL_BYPASS_DEBUG true + #include + #include + + FullLoopbackStream outgoingStream; + //AnalogAxisSimulator axis1(1); +#endif #if INCLUDE_WIFI #if USE_HARDCODED_CREDENTIALS @@ -107,6 +122,9 @@ FullLoopbackStream incomingStream; #include "SHDebouncer.h" #include "SHButton.h" + + + // ----------------------------------------------------- HW SETTINGS, PLEASE REVIEW ALL ------------------------------------------- #define ENABLE_MICRO_GAMEPAD 0 //{"Group":"GAMEPAD","Name":"ENABLE_MICRO_GAMEPAD","Title":"Enable arduino micro gamepad output for all the activated buttons/encoders","DefaultValue":"0","Type":"bool"} @@ -524,15 +542,15 @@ SHPWMPin shCONSPIN(CONS_PIN); #define GAMEPAD_AXIS_03_EXPONENTIALFACTOR 1 //{"Name":"GAMEPAD_AXIS_03_EXPONENTIALFACTOR","Title":"Brake axis exponential correction","DefaultValue":"1","Type":"double","Condition":"GAMEPAD_AXIS_03_ENABLED>0","dMin":0.1,"dMax":1.9} #if(GAMEPAD_AXIS_01_ENABLED == 1) -SHGamepadAxis SHGAMEPADAXIS01(GAMEPAD_AXIS_01_PIN, 0, GAMEPAD_AXIS_01_MINVALUE, GAMEPAD_AXIS_01_MAXVALUE, GAMEPAD_AXIS_01_SAMPLING, GAMEPAD_AXIS_01_EXPONENTIALFACTOR); +SHGamepadAxis SHGAMEPADAXIS01(GAMEPAD_AXIS_01_PIN, 0, GAMEPAD_AXIS_01_MINVALUE, GAMEPAD_AXIS_01_MAXVALUE, GAMEPAD_AXIS_01_SAMPLING, GAMEPAD_AXIS_01_EXPONENTIALFACTOR,axisStatusChanged); #endif #if(GAMEPAD_AXIS_02_ENABLED == 1) -SHGamepadAxis SHGAMEPADAXIS02(GAMEPAD_AXIS_02_PIN, 1, GAMEPAD_AXIS_02_MINVALUE, GAMEPAD_AXIS_02_MAXVALUE, GAMEPAD_AXIS_02_SAMPLING, GAMEPAD_AXIS_02_EXPONENTIALFACTOR); +SHGamepadAxis SHGAMEPADAXIS02(GAMEPAD_AXIS_02_PIN, 1, GAMEPAD_AXIS_02_MINVALUE, GAMEPAD_AXIS_02_MAXVALUE, GAMEPAD_AXIS_02_SAMPLING, GAMEPAD_AXIS_02_EXPONENTIALFACTOR,axisStatusChanged); #endif #if(GAMEPAD_AXIS_03_ENABLED == 1) -SHGamepadAxis SHGAMEPADAXIS03(GAMEPAD_AXIS_03_PIN, 2, GAMEPAD_AXIS_03_MINVALUE, GAMEPAD_AXIS_03_MAXVALUE, GAMEPAD_AXIS_03_SAMPLING, GAMEPAD_AXIS_03_EXPONENTIALFACTOR); +SHGamepadAxis SHGAMEPADAXIS03(GAMEPAD_AXIS_03_PIN, 2, GAMEPAD_AXIS_03_MINVALUE, GAMEPAD_AXIS_03_MAXVALUE, GAMEPAD_AXIS_03_SAMPLING, GAMEPAD_AXIS_03_EXPONENTIALFACTOR,axisStatusChanged); #endif #endif // INCLUDE_GAMEPAD @@ -542,61 +560,75 @@ 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 2 //{"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"} +#define BUTTON_TYPE_1 0 //{"Name":"BUTTON_TYPE_1","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=1","ListValues":"0,Physically Connected;1,Serialized"} -#define BUTTON_PIN_2 3 //{"Name":"BUTTON_PIN_2","Title":"2'nd Additional button digital pin","DefaultValue":"3","Type":"pin;Button 2","Condition":"ENABLED_BUTTONS_COUNT>=2"} +#define BUTTON_PIN_2 D4 //{"Name":"BUTTON_PIN_2","Title":"2'nd Additional button digital pin","DefaultValue":"3","Type":"pin;Button 2","Condition":"ENABLED_BUTTONS_COUNT>=2"} #define BUTTON_WIRINGMODE_2 0 //{"Name":"BUTTON_WIRINGMODE_2","Title":"2'nd Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=2","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_2 0 //{"Name":"BUTTON_LOGICMODE_2","Title":"2'nd Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=2","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_2 0 //{"Name":"BUTTON_TYPE_2","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=2","ListValues":"0,Physically Connected;1,Serialized"} -#define BUTTON_PIN_3 3 //{"Name":"BUTTON_PIN_3","Title":"3'rd Additional button digital pin","DefaultValue":"3","Type":"pin;Button 3","Condition":"ENABLED_BUTTONS_COUNT>=3"} +#define BUTTON_PIN_3 D5 //{"Name":"BUTTON_PIN_3","Title":"3'rd Additional button digital pin","DefaultValue":"3","Type":"pin;Button 3","Condition":"ENABLED_BUTTONS_COUNT>=3"} #define BUTTON_WIRINGMODE_3 0 //{"Name":"BUTTON_WIRINGMODE_3","Title":"3'rd Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=3","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_3 0 //{"Name":"BUTTON_LOGICMODE_3","Title":"3'rd Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=3","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_3 0 //{"Name":"BUTTON_TYPE_3","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=3","ListValues":"0,Physically Connected;1,Serialized"} -#define BUTTON_PIN_4 3 //{"Name":"BUTTON_PIN_4","Title":"4'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 4","Condition":"ENABLED_BUTTONS_COUNT>=4"} +#define BUTTON_PIN_4 D6 //{"Name":"BUTTON_PIN_4","Title":"4'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 4","Condition":"ENABLED_BUTTONS_COUNT>=4"} #define BUTTON_WIRINGMODE_4 0 //{"Name":"BUTTON_WIRINGMODE_4","Title":"4'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=4","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_4 0 //{"Name":"BUTTON_LOGICMODE_4","Title":"4'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=4","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_4 0 //{"Name":"BUTTON_TYPE_4","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=4","ListValues":"0,Physically Connected;1,Serialized"} -#define BUTTON_PIN_5 3 //{"Name":"BUTTON_PIN_5","Title":"5'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 5","Condition":"ENABLED_BUTTONS_COUNT>=5"} +#define BUTTON_PIN_5 D7 //{"Name":"BUTTON_PIN_5","Title":"5'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 5","Condition":"ENABLED_BUTTONS_COUNT>=5"} #define BUTTON_WIRINGMODE_5 0 //{"Name":"BUTTON_WIRINGMODE_5","Title":"5'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=5","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_5 0 //{"Name":"BUTTON_LOGICMODE_5","Title":"5'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=5","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_5 0 //{"Name":"BUTTON_TYPE_5","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=5","ListValues":"0,Physically Connected;1,Serialized"} #define BUTTON_PIN_6 3 //{"Name":"BUTTON_PIN_6","Title":"6'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 6","Condition":"ENABLED_BUTTONS_COUNT>=6"} #define BUTTON_WIRINGMODE_6 0 //{"Name":"BUTTON_WIRINGMODE_6","Title":"6'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=6","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_6 0 //{"Name":"BUTTON_LOGICMODE_6","Title":"6'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=6","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_6 0 //{"Name":"BUTTON_TYPE_6","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=6","ListValues":"0,Physically Connected;1,Serialized"} #define BUTTON_PIN_7 3 //{"Name":"BUTTON_PIN_7","Title":"7'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 7","Condition":"ENABLED_BUTTONS_COUNT>=7"} #define BUTTON_WIRINGMODE_7 0 //{"Name":"BUTTON_WIRINGMODE_7","Title":"7'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=7","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_7 0 //{"Name":"BUTTON_LOGICMODE_7","Title":"7'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=7","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_7 0 //{"Name":"BUTTON_TYPE_7","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=7","ListValues":"0,Physically Connected;1,Serialized"} -#define BUTTON_PIN_8 3 //{"Name":"BUTTON_PIN_8","Title":"8'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 8","Condition":"ENABLED_BUTTONS_COUNT>=8"} +#define BUTTON_PIN_8 1 //{"Name":"BUTTON_PIN_8","Title":"8'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 8","Condition":"ENABLED_BUTTONS_COUNT>=8"} #define BUTTON_WIRINGMODE_8 0 //{"Name":"BUTTON_WIRINGMODE_8","Title":"8'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=8","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_8 0 //{"Name":"BUTTON_LOGICMODE_8","Title":"8'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=8","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_8 0 //{"Name":"BUTTON_TYPE_8","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=8","ListValues":"0,Physically Connected;1,Serialized"} #define BUTTON_PIN_9 3 //{"Name":"BUTTON_PIN_9","Title":"9'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 9","Condition":"ENABLED_BUTTONS_COUNT>=9"} #define BUTTON_WIRINGMODE_9 0 //{"Name":"BUTTON_WIRINGMODE_9","Title":"9'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=9","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_9 0 //{"Name":"BUTTON_LOGICMODE_9","Title":"9'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=9","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_9 0 //{"Name":"BUTTON_TYPE_9","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=9","ListValues":"0,Physically Connected;1,Serialized"} #define BUTTON_PIN_10 3 //{"Name":"BUTTON_PIN_10","Title":"10'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 10","Condition":"ENABLED_BUTTONS_COUNT>=10"} #define BUTTON_WIRINGMODE_10 0 //{"Name":"BUTTON_WIRINGMODE_10","Title":"10'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=10","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_10 0 //{"Name":"BUTTON_LOGICMODE_10","Title":"10'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=10","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_10 0 //{"Name":"BUTTON_TYPE_10","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=10","ListValues":"0,Physically Connected;1,Serialized"} #define BUTTON_PIN_11 3 //{"Name":"BUTTON_PIN_11","Title":"11'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 11","Condition":"ENABLED_BUTTONS_COUNT>=11"} #define BUTTON_WIRINGMODE_11 0 //{"Name":"BUTTON_WIRINGMODE_11","Title":"11'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=11","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_11 0 //{"Name":"BUTTON_LOGICMODE_11","Title":"11'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=11","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_11 0 //{"Name":"BUTTON_TYPE_11","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=11","ListValues":"0,Physically Connected;1,Serialized"} -#define BUTTON_PIN_12 3 //{"Name":"BUTTON_PIN_12","Title":"12'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 12","Condition":"ENABLED_BUTTONS_COUNT>=12"} +#define BUTTON_PIN_12 42 //{"Name":"BUTTON_PIN_12","Title":"12'th Additional button digital pin","DefaultValue":"3","Type":"pin;Button 12","Condition":"ENABLED_BUTTONS_COUNT>=12"} #define BUTTON_WIRINGMODE_12 0 //{"Name":"BUTTON_WIRINGMODE_12","Title":"12'th Additional button wiring","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=12","ListValues":"0,Pin to GND;1,VCC to pin"} #define BUTTON_LOGICMODE_12 0 //{"Name":"BUTTON_LOGICMODE_12","Title":"12'th Additional button logic","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=12","ListValues":"0,Normal;1,Reversed"} +#define BUTTON_TYPE_12 0 //{"Name":"BUTTON_TYPE_12","Title":"Is virtual button","DefaultValue":"0","Type":"list","Condition":"ENABLED_BUTTONS_COUNT>=12","ListValues":"0,Physically Connected;1,Serialized"} int BUTTON_PINS[] = { BUTTON_PIN_1, BUTTON_PIN_2, BUTTON_PIN_3, BUTTON_PIN_4, BUTTON_PIN_5, BUTTON_PIN_6, BUTTON_PIN_7, BUTTON_PIN_8, BUTTON_PIN_9,BUTTON_PIN_10,BUTTON_PIN_11,BUTTON_PIN_12 }; int BUTTON_WIRING_MODES[] = { BUTTON_WIRINGMODE_1, BUTTON_WIRINGMODE_2, BUTTON_WIRINGMODE_3, BUTTON_WIRINGMODE_4, BUTTON_WIRINGMODE_5, BUTTON_WIRINGMODE_6, BUTTON_WIRINGMODE_7, BUTTON_WIRINGMODE_8, BUTTON_WIRINGMODE_9,BUTTON_WIRINGMODE_10,BUTTON_WIRINGMODE_11,BUTTON_WIRINGMODE_12 }; int BUTTON_LOGIC_MODES[] = { BUTTON_LOGICMODE_1, BUTTON_LOGICMODE_2, BUTTON_LOGICMODE_3, BUTTON_LOGICMODE_4, BUTTON_LOGICMODE_5, BUTTON_LOGICMODE_6, BUTTON_LOGICMODE_7, BUTTON_LOGICMODE_8, BUTTON_LOGICMODE_9, BUTTON_LOGICMODE_10, BUTTON_LOGICMODE_11, BUTTON_LOGICMODE_12 }; +int BUTTON_TYPE[]={BUTTON_TYPE_1,BUTTON_TYPE_2,BUTTON_TYPE_3,BUTTON_TYPE_4,BUTTON_TYPE_5,BUTTON_TYPE_6,BUTTON_TYPE_7,BUTTON_TYPE_8,BUTTON_TYPE_9,BUTTON_TYPE_10,BUTTON_TYPE_11,BUTTON_TYPE_12}; + SHButton button1, button2, button3, button4, button5, button6, button7, button8, button9, button10, button11, button12; SHButton* BUTTONS[] = { &button1, &button2, &button3, &button4, &button5, &button6, &button7, &button8 , &button9, &button10, &button11, &button12 }; @@ -608,68 +640,92 @@ SHDebouncer ButtonsDebouncer(10); // https://www.dx.com/p/ky-040-rotary-encoder-module-brick-sensor-development-for-arduino-avr-pic-420429#.W9BCM0sza0Q // Rotary encoders with pull-up resistors on the 3 outputs // ---------------------------------------------------------------------------------------------------------- -#define ENABLED_ENCODERS_COUNT 0 //{"Group":"Rotary Encoders","Name":"ENABLED_ENCODERS_COUNT","Title":"Rotary encoders enabled","DefaultValue":"0","Type":"int","Max":8} +#define ENABLED_ENCODERS_COUNT 1 //{"Group":"Rotary Encoders","Name":"ENABLED_ENCODERS_COUNT","Title":"Rotary encoders enabled","DefaultValue":"0","Type":"int","Max":8} #ifdef INCLUDE_ENCODERS #include "SHRotaryEncoder.h" -#define ENCODER1_CLK_PIN 7 //{"Name":"ENCODER1_CLK_PIN","Title":"Encoder 1 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 1 CLK","Condition":"ENABLED_ENCODERS_COUNT>0"} -#define ENCODER1_DT_PIN 8 //{"Name":"ENCODER1_DT_PIN","Title":"Encoder 1 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 1 DT","Condition":"ENABLED_ENCODERS_COUNT>0"} -#define ENCODER1_BUTTON_PIN 9 //{"Name":"ENCODER1_BUTTON_PIN","Title":"Encoder 1 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 1 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>0","Min":-1} -#define ENCODER1_ENABLE_PULLUP 0 //{"Name":"ENCODER1_ENABLE_PULLUP","Title":"Encoder 1 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>0"} +#if I2C_SERIAL_BYPASS && I2C_BYPASS_SLAVE + #include + SHRotaryEncoderContext virtualEncoderContext; + void VirtualEncoderPositionChanged(int encoderId,int position, byte direction); +#endif + +#define ENCODER1_CLK_PIN D5 //{"Name":"ENCODER1_CLK_PIN","Title":"Encoder 1 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 1 CLK","Condition":"ENABLED_ENCODERS_COUNT>0"} +#define ENCODER1_DT_PIN D6 //{"Name":"ENCODER1_DT_PIN","Title":"Encoder 1 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 1 DT","Condition":"ENABLED_ENCODERS_COUNT>0"} +#define ENCODER1_BUTTON_PIN D7 //{"Name":"ENCODER1_BUTTON_PIN","Title":"Encoder 1 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 1 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>0","Min":-1} +#define ENCODER1_BUTTON_TYPE 0 //{"Name":"ENCODER1_BUTTON_TYPE","Title":"Is virtual button encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>0","ListValues":"0,Physically Connected;1,Serialized"} +#define ENCODER1_ENABLE_PULLUP 1 //{"Name":"ENCODER1_ENABLE_PULLUP","Title":"Encoder 1 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>0"} #define ENCODER1_REVERSE_DIRECTION 0 //{"Name":"ENCODER1_REVERSE_DIRECTION","Title":"Encoder 1 reverse direction","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>0"} #define ENCODER1_ENABLE_HALFSTEPS 0 //{"Name":"ENCODER1_ENABLE_HALFSTEPS","Title":"Encoder 1 steps mode","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=1","ListValues":"0,Full steps;1,Half steps"} +#define ENCODER1_TYPE 0 //{"Name":"ENCODER1_TYPE","Title":"Is virtual encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>0","ListValues":"0,Physically Connected;1,Serialized"} -#define ENCODER2_CLK_PIN 11 //{"Name":"ENCODER2_CLK_PIN","Title":"Encoder 2 output A (CLK) pin","DefaultValue":"11","Type":"pin;Encoder 2 CLK","Condition":"ENABLED_ENCODERS_COUNT>1"} -#define ENCODER2_DT_PIN 12 //{"Name":"ENCODER2_DT_PIN","Title":"Encoder 2 output B (DT) pin","DefaultValue":"12","Type":"pin;Encoder 2 DT","Condition":"ENABLED_ENCODERS_COUNT>1"} -#define ENCODER2_BUTTON_PIN 13 //{"Name":"ENCODER2_BUTTON_PIN","Title":"Encoder 2 button (SW) pin","DefaultValue":"13","Type":"pin;Encoder 2 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>1","Min":-1} +#define ENCODER2_CLK_PIN 33 //{"Name":"ENCODER2_CLK_PIN","Title":"Encoder 2 output A (CLK) pin","DefaultValue":"11","Type":"pin;Encoder 2 CLK","Condition":"ENABLED_ENCODERS_COUNT>1"} +#define ENCODER2_DT_PIN 34 //{"Name":"ENCODER2_DT_PIN","Title":"Encoder 2 output B (DT) pin","DefaultValue":"12","Type":"pin;Encoder 2 DT","Condition":"ENABLED_ENCODERS_COUNT>1"} +#define ENCODER2_BUTTON_PIN 35 //{"Name":"ENCODER2_BUTTON_PIN","Title":"Encoder 2 button (SW) pin","DefaultValue":"13","Type":"pin;Encoder 2 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>1","Min":-1} +#define ENCODER2_BUTTON_TYPE 0 //{"Name":"ENCODER2_BUTTON_TYPE","Title":"Is virtual button encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>1","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER2_ENABLE_PULLUP 0 //{"Name":"ENCODER2_ENABLE_PULLUP","Title":"Encoder 2 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>1"} #define ENCODER2_REVERSE_DIRECTION 0 //{"Name":"ENCODER2_REVERSE_DIRECTION","Title":"Encoder 2 reverse direction","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>1"} #define ENCODER2_ENABLE_HALFSTEPS 0 //{"Name":"ENCODER2_ENABLE_HALFSTEPS","Title":"Encoder 2 steps mode","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=2","ListValues":"0,Full steps;1,Half steps"} +#define ENCODER2_TYPE 0 //{"Name":"ENCODER1_TYPE","Title":"Is virtual encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>1","ListValues":"0,Physically Connected;1,Serialized"} -#define ENCODER3_CLK_PIN 7 //{"Name":"ENCODER3_CLK_PIN","Title":"Encoder 3 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 3 CLK","Condition":"ENABLED_ENCODERS_COUNT>2"} -#define ENCODER3_DT_PIN 8 //{"Name":"ENCODER3_DT_PIN","Title":"Encoder 3 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 3 DT","Condition":"ENABLED_ENCODERS_COUNT>2"} -#define ENCODER3_BUTTON_PIN 9 //{"Name":"ENCODER3_BUTTON_PIN","Title":"Encoder 3 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 3 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>2","Min":-1} +#define ENCODER3_CLK_PIN D5 //{"Name":"ENCODER3_CLK_PIN","Title":"Encoder 3 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 3 CLK","Condition":"ENABLED_ENCODERS_COUNT>2"} +#define ENCODER3_DT_PIN D6 //{"Name":"ENCODER3_DT_PIN","Title":"Encoder 3 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 3 DT","Condition":"ENABLED_ENCODERS_COUNT>2"} +#define ENCODER3_BUTTON_PIN D7 //{"Name":"ENCODER3_BUTTON_PIN","Title":"Encoder 3 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 3 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>2","Min":-1} +#define ENCODER3_BUTTON_TYPE 0 //{"Name":"ENCODER3_BUTTON_TYPE","Title":"Is virtual button encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=3","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER3_ENABLE_PULLUP 0 //{"Name":"ENCODER3_ENABLE_PULLUP","Title":"Encoder 3 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>2"} #define ENCODER3_REVERSE_DIRECTION 0 //{"Name":"ENCODER3_REVERSE_DIRECTION","Title":"Encoder 3 reverse direction","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>2"} #define ENCODER3_ENABLE_HALFSTEPS 0 //{"Name":"ENCODER3_ENABLE_HALFSTEPS","Title":"Encoder 3 steps mode","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=3","ListValues":"0,Full steps;1,Half steps"} +#define ENCODER3_TYPE 0 //{"Name":"ENCODER3_TYPE","Title":"Is virtual encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=3","ListValues":"0,Physically Connected;1,Serialized"} -#define ENCODER4_CLK_PIN 7 //{"Name":"ENCODER4_CLK_PIN","Title":"Encoder 4 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 4 CLK","Condition":"ENABLED_ENCODERS_COUNT>3"} -#define ENCODER4_DT_PIN 8 //{"Name":"ENCODER4_DT_PIN","Title":"Encoder 4 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 4 DT","Condition":"ENABLED_ENCODERS_COUNT>3"} -#define ENCODER4_BUTTON_PIN 9 //{"Name":"ENCODER4_BUTTON_PIN","Title":"Encoder 4 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 4 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>3","Min":-1} +#define ENCODER4_CLK_PIN D5 //{"Name":"ENCODER4_CLK_PIN","Title":"Encoder 4 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 4 CLK","Condition":"ENABLED_ENCODERS_COUNT>3"} +#define ENCODER4_DT_PIN D6 //{"Name":"ENCODER4_DT_PIN","Title":"Encoder 4 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 4 DT","Condition":"ENABLED_ENCODERS_COUNT>3"} +#define ENCODER4_BUTTON_PIN D7 //{"Name":"ENCODER4_BUTTON_PIN","Title":"Encoder 4 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 4 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>3","Min":-1} +#define ENCODER4_BUTTON_TYPE 0 //{"Name":"ENCODER4_BUTTON_TYPE","Title":"Is virtual button encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>3","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER4_ENABLE_PULLUP 0 //{"Name":"ENCODER4_ENABLE_PULLUP","Title":"Encoder 4 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>3"} #define ENCODER4_REVERSE_DIRECTION 0 //{"Name":"ENCODER4_REVERSE_DIRECTION","Title":"Encoder 4 reverse direction","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>3"} #define ENCODER4_ENABLE_HALFSTEPS 0 //{"Name":"ENCODER4_ENABLE_HALFSTEPS","Title":"Encoder 4 steps mode","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=4","ListValues":"0,Full steps;1,Half steps"} +#define ENCODER4_TYPE 0 //{"Name":"ENCODER4_TYPE","Title":"Is virtual encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=4","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER5_CLK_PIN 7 //{"Name":"ENCODER5_CLK_PIN","Title":"Encoder 5 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 5 CLK","Condition":"ENABLED_ENCODERS_COUNT>4"} #define ENCODER5_DT_PIN 8 //{"Name":"ENCODER5_DT_PIN","Title":"Encoder 5 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 5 DT","Condition":"ENABLED_ENCODERS_COUNT>4"} #define ENCODER5_BUTTON_PIN 9 //{"Name":"ENCODER5_BUTTON_PIN","Title":"Encoder 5 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 5 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>4","Min":-1} +#define ENCODER5_BUTTON_TYPE 0 //{"Name":"ENCODER5_BUTTON_TYPE","Title":"Is virtual button encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=4","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER5_ENABLE_PULLUP 0 //{"Name":"ENCODER5_ENABLE_PULLUP","Title":"Encoder 5 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>4"} #define ENCODER5_REVERSE_DIRECTION 0 //{"Name":"ENCODER5_REVERSE_DIRECTION","Title":"Encoder 5 reverse direction","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>4"} #define ENCODER5_ENABLE_HALFSTEPS 0 //{"Name":"ENCODER5_ENABLE_HALFSTEPS","Title":"Encoder 5 steps mode","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=5","ListValues":"0,Full steps;1,Half steps"} +#define ENCODER5_TYPE 0 //{"Name":"ENCODER5_TYPE","Title":"Is virtual encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=5","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER6_CLK_PIN 7 //{"Name":"ENCODER6_CLK_PIN","Title":"Encoder 6 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 6 CLK","Condition":"ENABLED_ENCODERS_COUNT>5"} #define ENCODER6_DT_PIN 8 //{"Name":"ENCODER6_DT_PIN","Title":"Encoder 6 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 6 DT","Condition":"ENABLED_ENCODERS_COUNT>5"} #define ENCODER6_BUTTON_PIN 9 //{"Name":"ENCODER6_BUTTON_PIN","Title":"Encoder 6 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 6 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>5","Min":-1} +#define ENCODER6_BUTTON_TYPE 0 //{"Name":"ENCODER6_BUTTON_TYPE","Title":"Is virtual button encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=5","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER6_ENABLE_PULLUP 0 //{"Name":"ENCODER6_ENABLE_PULLUP","Title":"Encoder 6 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>5"} #define ENCODER6_REVERSE_DIRECTION 0 //{"Name":"ENCODER6_REVERSE_DIRECTION","Title":"Encoder 6 reverse direction","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>5"} #define ENCODER6_ENABLE_HALFSTEPS 0 //{"Name":"ENCODER6_ENABLE_HALFSTEPS","Title":"Encoder 6 steps mode","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=6","ListValues":"0,Full steps;1,Half steps"} +#define ENCODER6_TYPE 0 //{"Name":"ENCODER6_TYPE","Title":"Is virtual encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=6","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER7_CLK_PIN 7 //{"Name":"ENCODER7_CLK_PIN","Title":"Encoder 7 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 7 CLK","Condition":"ENABLED_ENCODERS_COUNT>6"} #define ENCODER7_DT_PIN 8 //{"Name":"ENCODER7_DT_PIN","Title":"Encoder 7 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 7 DT","Condition":"ENABLED_ENCODERS_COUNT>6"} #define ENCODER7_BUTTON_PIN 9 //{"Name":"ENCODER7_BUTTON_PIN","Title":"Encoder 7 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 7 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>6","Min":-1} +#define ENCODER7_BUTTON_TYPE 0 //{"Name":"ENCODER7_BUTTON_TYPE","Title":"Is virtual button encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=7","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER7_ENABLE_PULLUP 0 //{"Name":"ENCODER7_ENABLE_PULLUP","Title":"Encoder 7 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>6"} #define ENCODER7_REVERSE_DIRECTION 0 //{"Name":"ENCODER7_REVERSE_DIRECTION","Title":"Encoder 7 reverse direction","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>6"} #define ENCODER7_ENABLE_HALFSTEPS 0 //{"Name":"ENCODER7_ENABLE_HALFSTEPS","Title":"Encoder 7 steps mode","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=7","ListValues":"0,Full steps;1,Half steps"} +#define ENCODER7_TYPE 0 //{"Name":"ENCODER7_TYPE","Title":"Is virtual encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=7","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER8_CLK_PIN 7 //{"Name":"ENCODER8_CLK_PIN","Title":"Encoder 8 output A (CLK) pin","DefaultValue":"7","Type":"pin;Encoder 8 CLK","Condition":"ENABLED_ENCODERS_COUNT>7"} #define ENCODER8_DT_PIN 8 //{"Name":"ENCODER8_DT_PIN","Title":"Encoder 8 output B (DT) pin","DefaultValue":"8","Type":"pin;Encoder 8 DT","Condition":"ENABLED_ENCODERS_COUNT>7"} #define ENCODER8_BUTTON_PIN 9 //{"Name":"ENCODER8_BUTTON_PIN","Title":"Encoder 8 button (SW) pin","DefaultValue":"9","Type":"pin;Encoder 8 SWITCH","Condition":"ENABLED_ENCODERS_COUNT>7","Min":-1} +#define ENCODER8_BUTTON_TYPE 0 //{"Name":"ENCODER8_BUTTON_TYPE","Title":"Is virtual button encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>7","ListValues":"0,Physically Connected;1,Serialized"} #define ENCODER8_ENABLE_PULLUP 0 //{"Name":"ENCODER8_ENABLE_PULLUP","Title":"Encoder 8 enable pullup resistor","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>7"} #define ENCODER8_REVERSE_DIRECTION 0 //{"Name":"ENCODER8_REVERSE_DIRECTION","Title":"Encoder 8 reverse direction","DefaultValue":"0","Type":"bool","Condition":"ENABLED_ENCODERS_COUNT>7"} #define ENCODER8_ENABLE_HALFSTEPS 0 //{"Name":"ENCODER8_ENABLE_HALFSTEPS","Title":"Encoder 8 steps mode","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>=8","ListValues":"0,Full steps;1,Half steps"} +#define ENCODER8_TYPE 0 //{"Name":"ENCODER8_TYPE","Title":"Is virtual encoder","DefaultValue":"0","Type":"list","Condition":"ENABLED_ENCODERS_COUNT>7","ListValues":"0,Physically Connected;1,Serialized"} -SHRotaryEncoder encoder1, encoder2, encoder3, encoder4, encoder5, encoder6, encoder7, encoder8; -SHRotaryEncoder* SHRotaryEncoders[] = { &encoder1, &encoder2, &encoder3, &encoder4, &encoder5, &encoder6, &encoder7, &encoder8 }; +int ENCODER_TYPE[]={ENCODER1_TYPE,ENCODER2_TYPE,ENCODER3_TYPE,ENCODER4_TYPE,ENCODER5_TYPE,ENCODER6_TYPE,ENCODER7_TYPE,ENCODER8_TYPE}; +//SHRotaryEncoder encoder1, encoder2, encoder3, encoder4, encoder5, encoder6, encoder7, encoder8; +//SHRotaryEncoder* SHRotaryEncoders[] = { &encoder1, &encoder2, &encoder3, &encoder4, &encoder5, &encoder6, &encoder7, &encoder8 }; +SHRotaryEncoder* SHRotaryEncoders[ENABLED_ENCODERS_COUNT]; #endif // ----------------------- ROTARY ENCODERS ------------------------------------------------------------------ @@ -990,10 +1046,17 @@ 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(); #endif +#if I2C_SERIAL_BYPASS + //axis1.read(10); + + yield(); + I2CTransportManager::flush(); +#endif #if(GAMEPAD_AXIS_01_ENABLED == 1) SHGAMEPADAXIS01.read(); @@ -1018,7 +1081,13 @@ void idle(bool critical) { bool changed = false; #ifdef INCLUDE_BUTTONS for (int btnIdx = 0; btnIdx < ENABLED_BUTTONS_COUNT; btnIdx++) { - BUTTONS[btnIdx]->read(); + #if I2C_SERIAL_BYPASS + if(BUTTON_TYPE[btnIdx]==0){ + BUTTONS[btnIdx]->read(); + } + #else + BUTTONS[btnIdx]->read(); + #endif } #endif #ifdef INCLUDE_TM1638 @@ -1061,8 +1130,19 @@ void idle(bool critical) { } #ifdef INCLUDE_ENCODERS +void UpdateGamepadEncodersState(bool sendState); + +#if I2C_SERIAL_BYPASS && I2C_BYPASS_SLAVE +void VirtualEncoderPositionChanged(int encoderId,int position, byte direction) { + virtualEncoderContext.updateContext(encoderId,position,direction); +} +#endif + + void EncoderPositionChanged(int encoderId, int position, byte direction) { -#ifdef INCLUDE_GAMEPAD + +#if INCLUDE_GAMEPAD || ( INCLUDE_GAMEPAD && !I2C_BYPASS_MASTER && I2C_BYPASS_SLAVE && I2C_SERIAL_BYPASS) + UpdateGamepadEncodersState(true); #else if (direction < 2) { @@ -1071,32 +1151,59 @@ void EncoderPositionChanged(int encoderId, int position, byte direction) { arqserial.CustomPacketSendByte(direction); arqserial.CustomPacketSendByte(position); arqserial.CustomPacketEnd(); + } - else { + else { // BUTTON CLICK positionChangedCallback(id, counter, buttonState == HIGH ? 2 : 3); arqserial.CustomPacketStart(0x02, 2); arqserial.CustomPacketSendByte(encoderId); arqserial.CustomPacketSendByte(direction - 2); arqserial.CustomPacketEnd(); } + #endif } #endif + +/** + * + * +*/ +void axisStatusChanged(int axisId,int mappedValue){ + #if I2C_SERIAL_BYPASS + #if I2C_SERIAL_BYPASS_DEBUG + Serial.print("AxisStatusChanged"); + #endif + + arqserial.CustomPacketStart(0x13,3); + arqserial.CustomPacketSendByte(axisId); + arqserial.CustomPacketSendByte(highByte(mappedValue)); + arqserial.CustomPacketSendByte(lowByte(mappedValue)); + arqserial.CustomPacketEnd(); + #endif + } + +/** + * + * + * */ void buttonStatusChanged(int buttonId, byte Status) { -#ifdef INCLUDE_GAMEPAD +#ifdef INCLUDE_GAMEPAD && !I2C_BYPASS_MASTER Joystick.setButton(TM1638_ENABLEDMODULES * 8 + buttonId - 1, Status); Joystick.sendState(); #else - arqserial.CustomPacketStart(0x03, 2); - arqserial.CustomPacketSendByte(buttonId); - arqserial.CustomPacketSendByte(Status); - arqserial.CustomPacketEnd(); + arqserial.CustomPacketStart(0x03,2); + arqserial.CustomPacketSendByte(buttonId); + arqserial.CustomPacketSendByte(Status); + arqserial.CustomPacketEnd(); #endif } + + #ifdef INCLUDE_BUTTONMATRIX void buttonMatrixStatusChanged(int buttonId, byte Status) { -#ifdef INCLUDE_GAMEPAD +#ifdef INCLUDE_GAMEPAD && !I2C_BYPASS_MASTER Joystick.setButton(TM1638_ENABLEDMODULES * 8 + ENABLED_BUTTONS_COUNT + buttonId - 1, Status); Joystick.sendState(); #else @@ -1108,8 +1215,40 @@ void buttonMatrixStatusChanged(int buttonId, byte Status) { } #endif + + #if I2C_BYPASS_SLAVE + #include "SimHubProtocolDecoder.h" + + /*** ATTACH BEHAVIOURS WHEN IS IN SLAVE MODE*/ + EventCallBackManager callbacker; + + + + void receiveSerialProtocolViaI2c(int howMany){ + #if I2C_SERIAL_BYPASS_DEBUG + Serial.print("Received data via I2C with"); + Serial.print(howMany); + Serial.print(" Bytes"); + Serial.flush(); + #endif + decodeBuffer(&callbacker,&Wire); + } + + #endif + + +void InitEncoders() ; + +/***** + * + * SETUP DEVICES ENABLED +*/ void setup() { + + FlowSerialBegin(19200); + //while (!Serial1) ; // https://forum.arduino.cc/t/cant-view-serial-print-from-setup/167916 + #if INCLUDE_WIFI #if DEBUG_TCP_BRIDGE Serial.begin(115200); @@ -1120,6 +1259,15 @@ void setup() ECrowneWifi::setup(&outgoingStream, &incomingStream); #endif +#if I2C_SERIAL_BYPASS + Serial.begin(115200); + while(!Serial); + Serial.println("MAIN - SETUP - I2C_SERIAL_BYPASS"); + + I2CTransportManager::setup(&outgoingStream); + //axis1.setCallBack(axisStatusChanged); + +#endif //#ifdef INCLUDE_TEMPGAUGE // shTEMPPIN.SetValue((int)80); //#endif @@ -1127,8 +1275,42 @@ void setup() #ifdef INCLUDE_FUELGAUGE shFUELPIN.SetValue((int)80); #endif + + +#if I2C_BYPASS_SLAVE + Serial.println("MAIN - SETUP - I2C_SERIAL_BYPASS AS SLAVE"); + #ifdef INCLUDE_BUTTONS + callbacker.setButtonCallBack(buttonStatusChanged); + #endif + +// callbacker.setAnalogAxisChangedEventCallback(analogAxisChangedEventCallback); + Wire.begin(I2C_BYPASS_SLAVE_ADRESS); /* join i2c bus with address 8 */ + Wire.setWireTimeout(1000); + Wire.onReceive(receiveSerialProtocolViaI2c); + + // TODO: IN ENCODERS BRANCH + #ifdef INCLUDE_ENCODERS + callbacker.setEncoderPositionChangedCallback(VirtualEncoderPositionChanged); + #endif + + #endif + +#if I2C_BYPASS_MASTER + #if I2C_SERIAL_BYPASS_DEBUG + Serial.println("MAIN - SETUP - I2C_SERIAL_BYPASS"); + #endif + //I2CTransportManager::setup(&outgoingStream); + + /// TEST TRANSPORT + // Serial.println("Lanzando prueba del canal I2C"); + // StreamWrite("t"); + // StreamWrite("e"); + // StreamWrite("s"); + // StreamWrite("t"); + //// + //axis1.setCallBack(axisStatusChanged); +#endif - FlowSerialBegin(19200); #ifdef INCLUDE_GAMEPAD Joystick.begin(false); @@ -1235,7 +1417,7 @@ void setup() shMatrixHT16H33SingleColor.begin(ADA_HT16K33_SINGLECOLORMATRIX_I2CADDRESS); #endif -#ifdef INCLUDE_OLED +#ifdef INCLUDE_OLEDPus shGLCD.Init(); #endif @@ -1246,7 +1428,13 @@ void setup() #ifdef INCLUDE_BUTTONS // EXTERNAL BUTTONS INIT for (int btnIdx = 0; btnIdx < ENABLED_BUTTONS_COUNT; btnIdx++) { - BUTTONS[btnIdx]->begin(btnIdx + 1, BUTTON_PINS[btnIdx], buttonStatusChanged, BUTTON_WIRING_MODES[btnIdx], BUTTON_LOGIC_MODES[btnIdx]); + #if I2C_SERIAL_BYPASS + if(BUTTON_TYPE[btnIdx]==0){ + BUTTONS[btnIdx]->begin(btnIdx + 1, BUTTON_PINS[btnIdx], buttonStatusChanged, BUTTON_WIRING_MODES[btnIdx], BUTTON_LOGIC_MODES[btnIdx]); + } + #else + BUTTONS[btnIdx]->begin(btnIdx + 1, BUTTON_PINS[btnIdx], buttonStatusChanged, BUTTON_WIRING_MODES[btnIdx], BUTTON_LOGIC_MODES[btnIdx]); + #endif } #endif @@ -1311,15 +1499,48 @@ void setup() } #ifdef INCLUDE_ENCODERS +#include void InitEncoders() { - if (ENABLED_ENCODERS_COUNT > 0) encoder1.begin(ENCODER1_CLK_PIN, ENCODER1_DT_PIN, ENCODER1_BUTTON_PIN, ENCODER1_REVERSE_DIRECTION, ENCODER1_ENABLE_PULLUP, 1, ENCODER1_ENABLE_HALFSTEPS, EncoderPositionChanged); - if (ENABLED_ENCODERS_COUNT > 1) encoder2.begin(ENCODER2_CLK_PIN, ENCODER2_DT_PIN, ENCODER2_BUTTON_PIN, ENCODER2_REVERSE_DIRECTION, ENCODER2_ENABLE_PULLUP, 2, ENCODER2_ENABLE_HALFSTEPS, EncoderPositionChanged); - if (ENABLED_ENCODERS_COUNT > 2) encoder3.begin(ENCODER3_CLK_PIN, ENCODER3_DT_PIN, ENCODER3_BUTTON_PIN, ENCODER3_REVERSE_DIRECTION, ENCODER3_ENABLE_PULLUP, 3, ENCODER3_ENABLE_HALFSTEPS, EncoderPositionChanged); - if (ENABLED_ENCODERS_COUNT > 3) encoder4.begin(ENCODER4_CLK_PIN, ENCODER4_DT_PIN, ENCODER4_BUTTON_PIN, ENCODER4_REVERSE_DIRECTION, ENCODER4_ENABLE_PULLUP, 4, ENCODER4_ENABLE_HALFSTEPS, EncoderPositionChanged); - if (ENABLED_ENCODERS_COUNT > 4) encoder5.begin(ENCODER5_CLK_PIN, ENCODER5_DT_PIN, ENCODER5_BUTTON_PIN, ENCODER5_REVERSE_DIRECTION, ENCODER5_ENABLE_PULLUP, 5, ENCODER5_ENABLE_HALFSTEPS, EncoderPositionChanged); - if (ENABLED_ENCODERS_COUNT > 5) encoder6.begin(ENCODER6_CLK_PIN, ENCODER6_DT_PIN, ENCODER6_BUTTON_PIN, ENCODER6_REVERSE_DIRECTION, ENCODER6_ENABLE_PULLUP, 6, ENCODER6_ENABLE_HALFSTEPS, EncoderPositionChanged); - if (ENABLED_ENCODERS_COUNT > 6) encoder7.begin(ENCODER7_CLK_PIN, ENCODER7_DT_PIN, ENCODER7_BUTTON_PIN, ENCODER7_REVERSE_DIRECTION, ENCODER7_ENABLE_PULLUP, 7, ENCODER7_ENABLE_HALFSTEPS, EncoderPositionChanged); - if (ENABLED_ENCODERS_COUNT > 7) encoder8.begin(ENCODER8_CLK_PIN, ENCODER8_DT_PIN, ENCODER8_BUTTON_PIN, ENCODER8_REVERSE_DIRECTION, ENCODER8_ENABLE_PULLUP, 8, ENCODER8_ENABLE_HALFSTEPS, EncoderPositionChanged); + for(int i=0;ibegin(ENCODER1_CLK_PIN, ENCODER1_DT_PIN, ENCODER1_BUTTON_PIN, ENCODER1_REVERSE_DIRECTION, ENCODER1_ENABLE_PULLUP, 1, ENCODER1_ENABLE_HALFSTEPS, EncoderPositionChanged); + break; + case 1: + SHRotaryEncoders[1]->begin(ENCODER2_CLK_PIN, ENCODER2_DT_PIN, ENCODER2_BUTTON_PIN, ENCODER2_REVERSE_DIRECTION, ENCODER2_ENABLE_PULLUP, 2, ENCODER2_ENABLE_HALFSTEPS, EncoderPositionChanged); + break; + case 2: + SHRotaryEncoders[2]->begin(ENCODER3_CLK_PIN, ENCODER3_DT_PIN, ENCODER3_BUTTON_PIN, ENCODER3_REVERSE_DIRECTION, ENCODER3_ENABLE_PULLUP, 3, ENCODER3_ENABLE_HALFSTEPS, EncoderPositionChanged); + break; + case 3: + SHRotaryEncoders[3]->begin(ENCODER4_CLK_PIN, ENCODER4_DT_PIN, ENCODER4_BUTTON_PIN, ENCODER4_REVERSE_DIRECTION, ENCODER4_ENABLE_PULLUP, 4, ENCODER4_ENABLE_HALFSTEPS, EncoderPositionChanged); + break; + case 4: + SHRotaryEncoders[4]->begin(ENCODER5_CLK_PIN, ENCODER5_DT_PIN, ENCODER5_BUTTON_PIN, ENCODER5_REVERSE_DIRECTION, ENCODER5_ENABLE_PULLUP, 5, ENCODER5_ENABLE_HALFSTEPS, EncoderPositionChanged); + break; + case 5: + SHRotaryEncoders[5]->begin(ENCODER6_CLK_PIN, ENCODER6_DT_PIN, ENCODER6_BUTTON_PIN, ENCODER6_REVERSE_DIRECTION, ENCODER6_ENABLE_PULLUP, 6, ENCODER6_ENABLE_HALFSTEPS, EncoderPositionChanged); + break; + case 6: + SHRotaryEncoders[6]->begin(ENCODER7_CLK_PIN, ENCODER7_DT_PIN, ENCODER7_BUTTON_PIN, ENCODER7_REVERSE_DIRECTION, ENCODER7_ENABLE_PULLUP, 7, ENCODER7_ENABLE_HALFSTEPS, EncoderPositionChanged); + break; + case 7: + SHRotaryEncoders[7]->begin(ENCODER8_CLK_PIN, ENCODER8_DT_PIN, ENCODER8_BUTTON_PIN, ENCODER8_REVERSE_DIRECTION, ENCODER8_ENABLE_PULLUP, 8, ENCODER8_ENABLE_HALFSTEPS, EncoderPositionChanged); + break; + + default: + break; + } + + } + } #endif @@ -1339,41 +1560,68 @@ void UpdateGamepadState() { #endif #ifdef INCLUDE_ENCODERS +// Serial.print("DisplayClientV2:UpdateGamepadState ->"); UpdateGamepadEncodersState(false); #endif - Joystick.sendState(); } + + + #ifdef INCLUDE_ENCODERS + void UpdateGamepadEncodersState(bool sendState) { int btnidx = TM1638_ENABLEDMODULES * 8 + ENABLED_BUTTONS_COUNT + ENABLED_BUTTONMATRIX * (BMATRIX_COLS * BMATRIX_ROWS); unsigned long refTime = millis(); - for (int i = 0; i < ENABLED_ENCODERS_COUNT; i++) { - uint8_t dir = SHRotaryEncoders[i]->getDirection(MICRO_GAMEPAD_ENCODERPRESSTIME, refTime); - Joystick.setButton(btnidx, dir == 0); - Joystick.setButton(btnidx + 1, dir == 1); - Joystick.setButton(btnidx + 2, SHRotaryEncoders[i]->getPressed()); - btnidx += 3; + + for (int i = 0; i < ENABLED_ENCODERS_COUNT; i++) { + //delay(300); + // Serial.print(" UpdateGamepadEncodersState :: "); + // Serial.print(sendState); + // Serial.print("::ENCODER - "); + // Serial.print(i); + // Serial.print(" -> "); + //Serial.print(SHRotaryEncoders[i]->getPressed()); + //if(ENCODER_TYPE[i]==0){ + uint8_t dir = SHRotaryEncoders[i]->getDirection(MICRO_GAMEPAD_ENCODERPRESSTIME, refTime); + // Serial.print(dir); + // Serial.print(","); + Joystick.setButton(btnidx, dir == 0); + Joystick.setButton(btnidx + 1, dir == 1); + Joystick.setButton(btnidx + 2, SHRotaryEncoders[i]->getPressed()); + btnidx += 3; + + //} + } if (sendState) Joystick.sendState(); } #endif + #endif + + char loop_opt; char xactionc; unsigned long lastSerialActivity = 0; - - +/**** + * + * MAIN LOOP +*/ void loop() { #if INCLUDE_WIFI ECrowneWifi::loop(); #endif +#if I2C_SERIAL_BYPASS + I2CTransportManager::loop(); +#endif + #ifdef INCLUDE_SHAKEITL298N shShakeitL298N.safetyCheck(); #endif @@ -1398,7 +1646,11 @@ void loop() { #ifdef INCLUDE_GAMEPAD UpdateGamepadState(); #endif + + shCustomProtocol.loop(); + //delay(1000); + //Serial.printf("\nI'm alive\n"); // Wait for data if (FlowSerialAvailable() > 0) { @@ -1407,7 +1659,7 @@ void loop() { lastSerialActivity = millis(); // Read command loop_opt = FlowSerialTimedRead(); - + switch(loop_opt) { case '1': Command_Hello(); break; case '8': Command_SetBaudrate(); break; @@ -1449,3 +1701,4 @@ void loop() { Command_Shutdown(); } } +