Reading two values

I'm currently trying to read two different bytes that I send from my PC to the Arduino.
When I try sending only one, I receive it and everything works fine.
But for my purpose I need to wait for both values, and then do something with them.
My Arduino code is the following:

#include <USBController.h>

void setup() {
 
  delay(1000); 
  Mouse.begin(); 
  test[0] = 0;
  test[1] = 0;

 } 
 
void loop() {
  int recv = controller.read();
  if(recv != 0) {
    if(test[0] != 0) {
      test[1] = recv;
	  //DO SOMETHING
      test[1] = 0;
      test[0] = 0;
    } else {
      test[0] = recv;
    }
  }

Here is how I'm sending the bytes:

buf[0] = 2; //Report ID
buf[1] = 50; //data
buf2[0] = 2; //Report ID
buf2[1] = 100; //Data

std::cout << First send!  << \n;
hid_write(handle, buf, 65);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << Second send!  << \n;
hid_write(handle, buf, 65);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));

I'm communicating with the Arduino via. HID, Serial Communication is not an option.
I can't use Serial Monitor to debug the error, but I still tried to debug the error by sending the bytes back to the pc.
While debugging I found out that at the point where I would do something with the bytes test0] equals 0 and the other one is alternatly 50 or 100 I tried changing something but just can't get it to work.
I also sadly can't use Prefixes to sort the receiving data.
Arduino doesn't support receiving data by default so I had to change some things arround.
But as said at the beginning, sending just one value and doing something with it works just fine.
If anyone has a better idea to solve my problem or knows why my arduino is acting up,
I would highly appreciate telling me.
Thanks in advance.

I would suggest to study Serial Input Basics to handle this

You might not be using an UART but you are still dealing with a Serial communication so the concept stays the same (where is USBController.h coming from?)

I appreciate your message, but Im extremly sure that the reading works fine and the normal Serial Communication given by the Arduino is not a option in my case of use.
USBController.h is a part of a library that allows the arduino to receive data via. HID.

Sorry, the question was which one is it? (link)

what does int recv = controller.read(); this return when there is noting to read ?

I checked it to make sure, but as expected it returns 0.

so you can't send byte whose value is 0 ?

the library link would help..

I actually can, If I send the value 0 it still comes past the

if(recv != 0)

These are the two files needed:
USBController.h

#ifndef USBController_h
#define USBController_h
#include "Arduino.h"

// make sure that it is a supported Architecture
#ifndef ARDUINO_ARCH_AVR
#error "Unsupported Architecture"
#endif

#include "PluggableUSB.h"
#include "HID.h"

#define USBController_D_HIDREPORT(length) { 9, 0x21, 0x11, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) }
typedef struct {
	InterfaceDescriptor hid;
  HIDDescDescriptor desc;
  EndpointDescriptor in;
	EndpointDescriptor out;
} USBControllerHIDDescriptor;
typedef union {
	uint8_t dataInHeader[0];
	uint8_t dataInBlock[0];
	uint8_t dataOutHeader[0];
	uint8_t dataOutBlock[0];
	struct {
		uint8_t dataIn;
		uint8_t dataOut;
	};
} USBControllerDataPacket;

static const uint8_t USBControllerReportDescriptor[] PROGMEM = {
	0x06, 0x00, 0xff,              // USAGE_PAGE (vendor defined page 1)
	0x09, 0x00,                    // USAGE (Undefined)
	0xa1, 0x01,                    // COLLECTION (Application)
	0x85, 0x01,                    //   REPORT_ID (1)
	0x09, 0x00,                    //   USAGE (Undefined)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
	0x75, 0x08,                    //   REPORT_SIZE (8)
	0x95, 0x01,                    //   REPORT_COUNT (1)
	0x81, 0x06,                    //   INPUT (Data,Var,Rel)
	0x85, 0x02,                    //   REPORT_ID (2)
	0x09, 0x00,                    //   USAGE (Undefined)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
	0x75, 0x08,                    //   REPORT_SIZE (8)
	0x95, 0x01,                    //   REPORT_COUNT (1)
	0x91, 0x06,                    //   OUTPUT (Data,Var,Rel)
	0xc0                           // END_COLLECTION
};

#define USBControllerInterface pluggedInterface
#define USBControllerEndpointIn pluggedEndpoint
#define USBControllerEndpointOut (pluggedEndpoint + 1)
#define USBControllerTX USBControllerEndpointIn
#define USBControllerRX USBControllerEndpointOut

class USBController : public PluggableUSBModule {
public:
	USBController();
	int write(const uint8_t *buffer, size_t size);
	int read();
private:

protected:
	uint8_t endpointTypes[2];
	uint8_t protocol;
	uint8_t idle;

	int getInterface(uint8_t *interfaceNumber);
	int getDescriptor(USBSetup &setup);
	bool setup(USBSetup &setup);
};

#endif // USBController_h import guard

USBController.cpp

#include "USBController.h"
#include "Arduino.h"

USBController::USBController() : PluggableUSBModule(2, 1, endpointTypes) {
	endpointTypes[0] = EP_TYPE_BULK_IN;
	endpointTypes[1] = EP_TYPE_INTERRUPT_OUT;
	PluggableUSB().plug(this);
}

int USBController::getInterface(uint8_t *interfaceNumber) {
	interfaceNumber[0] += 1;
	USBControllerHIDDescriptor interfaceDescriptor = {
		D_INTERFACE(USBControllerInterface, 2, USB_DEVICE_CLASS_HUMAN_INTERFACE, 0, 0),
		USBController_D_HIDREPORT(sizeof(USBControllerReportDescriptor)),
		D_ENDPOINT(USB_ENDPOINT_IN(USBControllerEndpointIn), USB_ENDPOINT_TYPE_BULK, USB_EP_SIZE, 0),
		D_ENDPOINT(USB_ENDPOINT_OUT(USBControllerEndpointOut), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0),
	};
	return USB_SendControl(0, &interfaceDescriptor, sizeof(interfaceDescriptor));
}

int USBController::getDescriptor(USBSetup &setup) {
	// code copied and modified from NicoHood's HID-Project
	// check if it is a HID class Descriptor request
	if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; }
	if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; }

	// In a HID Class Descriptor wIndex cointains the interface number
	if (setup.wIndex != pluggedInterface) { return 0; }

	protocol = HID_REPORT_PROTOCOL;

	return USB_SendControl(TRANSFER_PGM, USBControllerReportDescriptor, sizeof(USBControllerReportDescriptor));
}

bool USBController::setup(USBSetup &setup) {
	// code copied from NicoHood's HID-Project
	if (pluggedInterface != setup.wIndex) {
		return false;
	}

	uint8_t request = setup.bRequest;
	uint8_t requestType = setup.bmRequestType;

	if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
	{
		if (request == HID_GET_REPORT) {
			// TODO: HID_GetReport();
			return true;
		}
		if (request == HID_GET_PROTOCOL) {
			// TODO: Send8(protocol);
			return true;
		}
	}

	if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
	{
		if (request == HID_SET_PROTOCOL) {
			protocol = setup.wValueL;
			return true;
		}
		if (request == HID_SET_IDLE) {
			idle = setup.wValueL;
			return true;
		}
		if (request == HID_SET_REPORT)
		{
		}
	}

	return false;
}

int USBController::write(const uint8_t *buffer, size_t size) {
	return USB_Send(USBControllerTX, buffer, size);
}

int USBController::read() {
	if (USB_Available(USBControllerRX)) {
		return USB_Recv(USBControllerRX);
	}
	else {
		return 0;
	}
}

I appreciate your help and let me know if you need anything else.

a link to the library please... they usually have tons more of information...

Sadly, there is no official library post.
These two files were made by a guy back in 2019:

I have worked with his method of receiving data through HID and never had a problem.

can you clarify the Arduino and boot loader you are using?

do you have a spare FT232RL Serial adapter or an LCD that you could use to help debug?

I'm using the arduino leonardo, with a custom bootloader and disabled Serial Communication.
I don't have any spareparts, I'm currently debugging by moving my mouse via. the official mouse library.

can you use the builtin LED to do something like this

#include <USBController.h>
const byte ledPin = 13;

void blink(byte n) {
  for (byte i = 0; i < n; i++) {
    digitalWrite(ledPin, HIGH);
    delay(300);
    digitalWrite(ledPin, LOW);
    delay(100);
  }
}

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int recv = controller.read();
  if (recv != 0) {
    byte r = recv;
    blink(r);
    delay(1000);
  }
}

the builtin LED should blink a number of time that matches the code you sent and take 1s pause

if you send

buf[0] = 2; //Report ID
buf[1] = 5; //data
buf2[0] = 2; //Report ID
buf2[1] = 10; //Data

do you see 5 blinks followed by 10 blinks ?

After debugging with your approach I found the problem.
The Problem was the return value of controller.read().
The function somehow randomly returns 2 and screws up the counter.
If I had looked closer when you were asking me what the return value of it is, I would've not been debugging for the past three hours...
Thank you sooo much for being so kind and helping me!

Glad it helped

Have fun

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.