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

Adds support for the IBUS protocol #125

Open
HakuyaSakuragi opened this issue Jul 14, 2024 · 6 comments
Open

Adds support for the IBUS protocol #125

HakuyaSakuragi opened this issue Jul 14, 2024 · 6 comments

Comments

@HakuyaSakuragi
Copy link

This project is outstanding! I hope it can support the IBUS protocol.

@bsvdoom
Copy link
Contributor

bsvdoom commented Oct 7, 2024

Maybe this library can be implemented with IBUSBM_NOTIMER on ESP32:
https://github.com/bmellink/IBusBM

@Zuhayer69
Copy link

Have anyone of you succeed in getting ibus protocol to work with ESP 32? If you have then how? Please tell in details

@rtlopez
Copy link
Owner

rtlopez commented Nov 24, 2024

IBUS is not implemented yet. What receiver are you using?

@HakuyaSakuragi
Copy link
Author

I implemented the IBUS protocol myself, but given that I'm a nooob in c++ and embedded don't consider submitting it, here's my code

inputIBUS.h

#include "Device/SerialDevice.h"
#include "Device/InputDevice.h"
#include "Logger.h"

namespace Espfc {

namespace Device {

class InputIBUS : public InputDevice 
{
    //一帧32字节
    struct IBusData {
        uint8_t Head1;                 //1
        uint8_t Head2;                 //2
        uint16_t CH1     : 12;      //3-4
        uint16_t CH2     : 12;      //5-6
        uint16_t CH3     : 12;      //7-8
        uint16_t CH4     : 12;      //9-10
        uint16_t CH5     : 12;      //11-12
        uint16_t CH6     : 12;      //13-14
        uint16_t CH7     : 12;      //15-16
        uint16_t CH8     : 12;      //17-18
        uint16_t CH9     : 12;      //19-20
        uint16_t CH10    : 12;      //21-22
        uint16_t CH11    : 12;      //23-24
        uint16_t CH12    : 12;      //25-26
        uint16_t CH13    : 12;      //27-28
        uint16_t CH14    : 12;      //29-30

        uint8_t checkSum1;              //31
        uint8_t checkSum2;              //32
    } __attribute__ ((__packed__));
    
  public:
    enum IbusState{
        IBUS_START,
        IBUS_DATA,
        IBUS_END
    };



    int begin(Device::SerialDevice * serial);
    InputStatus update() override;
    uint16_t get(uint8_t i) const override;
    void get(uint16_t * data, size_t len) const override;
    size_t getChannelCount() const override;
    bool needAverage() const override;
    
    //日志
    void SetLogger(Logger& log);
    //构造函数
    InputIBUS();

    private:
        const static size_t IBUS_FRAME_SIZE = sizeof(IBusData);
        static const size_t CHANNELS = 14;
        Device::SerialDevice * _serial;
        IbusState _state;
        uint8_t _idx = 0;
        bool _new_data;

        //bool validate();
        Logger* ibusLogger;
        uint8_t _data[IBUS_FRAME_SIZE];
        uint16_t _channels[CHANNELS];
        //uint8_t _flags;
};


}
}

inputIBUS.cpp

#include "InputIBUS.h"
#include "Utils/MemoryHelper.h"

namespace Espfc {
namespace Device{

//////////////////////////////////////////////////////////////
InputIBUS::InputIBUS(): _serial(NULL), _state(IBUS_START), _idx(0), _new_data(false) {}

int InputIBUS::begin(Device::SerialDevice * serial)
{
    _serial = serial;
    
    for(size_t i = 0; i < IBUS_FRAME_SIZE; i++)
    {
        _data[i] = 0;
        if(i < CHANNELS) _channels[i] = 0;
    }

    if (ibusLogger != NULL)
    {
        ibusLogger->logln("ALT5Debug:IBUS START!");
    }
    return 1;
}

void InputIBUS::SetLogger(Logger& log)
{
    ibusLogger = &log;
    ibusLogger->logln("ALT5Debug:Logger Set");
}

InputStatus FAST_CODE_ATTR InputIBUS::update()
{   
    if(!_serial) return INPUT_IDLE;
    size_t len = _serial->available();

    if (len) {
        uint8_t buff[32] = {0};
        len = std::min(len, sizeof(buff));
        _serial->readMany(buff, len);
        
        //解析
        if (buff[0] != 0x20 || buff[1] != 0x40) return INPUT_LOST;

        //验证
        uint8_t index = 0;
        uint8_t offset = 2;
        size_t end = len - 2;
        uint32_t checkSum = 0x20+0x40;  

        for (offset = 2; offset < end; offset+=2,index++){
            _channels[index] =((buff[offset+1] & 0b1111) << 8) | buff[offset];
            checkSum += buff[offset]+buff[offset+1];
        }

        checkSum ^= 0xFFFF;
        bool sum1 =  (checkSum & 0x00FF) == buff[30];
        bool sum2 =  (checkSum & 0xFF00 >> 8) == buff[31];

        if (sum1 && sum2) return INPUT_IDLE;

        return  INPUT_RECEIVED;  
    }

    //如果接收到新数据
    if (_new_data){_new_data = false;}
    return INPUT_IDLE;
}

uint16_t FAST_CODE_ATTR InputIBUS::get(uint8_t i) const
{
  return _channels[i];
}

void FAST_CODE_ATTR InputIBUS::get(uint16_t * data, size_t len) const
{
  const uint16_t * src = _channels;
  while(len--)
  {
    *data++ = *src++;
  }
}

size_t InputIBUS::getChannelCount() const { return CHANNELS; }

bool InputIBUS::needAverage() const { return false; }
//////////////////////////////////////////////////////////////

}
}

Have anyone of you succeed in getting ibus protocol to work with ESP 32? If you have then how? Please tell in details

@HakuyaSakuragi
Copy link
Author

IBUS is not implemented yet. What receiver are you using?

I actually made one myself, I used a gamepad as an input and then made a rudimentary, receiver similar to this one

24c80b8b9e76a0f3d08031f6df6a59f1

@bsvdoom
Copy link
Contributor

bsvdoom commented Jan 14, 2025

Nice job!
If this works, you should definitely publish a PR, it will be reviewed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants