I wrote the following program to communicate with with an Arduino UNO. This test program let the user send one byte at a time from PC to the Arduino board. If the broad received byte sequence 65,71,67,68 UNO broad will blink the built-in LED and write the same sequence 65,71,67,68 to the serial buffer. Otherwise the broad does nothing.The Arduino sketch I wrote works as intended(I checked it using the serial monitor).
But the C++ program doesn't always receive the full byte sequence.
Received sequence can be (65,71,67,68) or (65,71,67) or (65,71) or 65 or 0 in different iterations. some insight would be greatly appreciated.
#include "libusb.h"
#include <iostream>`
#include <stdio.h>`
#include <string.h>`
#include <unistd.h>`
libusb_device_handle *dev_handle;
libusb_context *ctx = NULL;
static int ENDPOINT_IN = 0x83;
static int ENDPOINT_OUT = 0x04;
static const int USB_TIMEOUT = 2000;
int CLOSE_DEVICE();
int OPEN_DEVICE();
int main(){
if(OPEN_DEVICE()!=0){
printf("Device Open Failed!\n");
libusb_close(dev_handle);
libusb_exit(ctx);
return -1;
}
int rc=-1;
unsigned char encoding[] = { 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 }; //9600 1N8
rc = libusb_control_transfer(dev_handle,0x21, 0x20, 0, 0, encoding,7, 0);
if (rc < 0) {
printf("ERROR IN CONTROL TRANSFER!\n");
}
unsigned char cUsbBuf[64]={0,0,0,0};
unsigned char iUsbBuf[64]={0,0,0,0};
int nBytes=0;
int status =-1;
unsigned int character=0;
while(1){
printf("send byte:");
scanf("%u",&character);
if(character==255){
break;
}else{
cUsbBuf[0] = static_cast<unsigned char>(character);
}
status = libusb_bulk_transfer(dev_handle, (ENDPOINT_OUT|LIBUSB_ENDPOINT_OUT),cUsbBuf,1,&nBytes, USB_TIMEOUT);
if(status<0){
printf("TRANSFER ERROR:%s\n",libusb_error_name(status));
}
printf(")ut Bytes:%d\n",nBytes);
usleep(2000000);
status = libusb_bulk_transfer(dev_handle,(ENDPOINT_IN|LIBUSB_ENDPOINT_IN),iUsbBuf,4,&nBytes, USB_TIMEOUT);
if(status<0){
printf("TRANSFER ERROR:%s\n",libusb_error_name(status));
}
printf("in Bytes:%d\n",nBytes);
for(int i=0;i<4;++i){
printf("%d ", iUsbBuf[i]);
iUsbBuf[i]=0;
}
printf("\n\n\n");
nBytes=0;
}
CLOSE_DEVICE();
return 0;
}
int CLOSE_DEVICE(){
if(libusb_release_interface(dev_handle, 0)!=0){ //release the claimed interface 0
printf("Error releasing interface 0 !\n",1);
return -1;
}
if(libusb_release_interface(dev_handle, 1)!=0){ //release the claimed interface 1
printf("Error releasing interface 1 !\n",1);
return -1;
}
libusb_close(dev_handle);
libusb_exit(ctx);
return 0;
}
int OPEN_DEVICE(){
libusb_device **devs;
ssize_t cnt;
if(libusb_init(&ctx)<0){
printf("ERROR INIT!");
return -1;
}
cnt=libusb_get_device_list(ctx, &devs);
dev_handle = libusb_open_device_with_vid_pid(ctx,0x2341,0x0043); //ARIDUNO UNO VENDER and DEVICE ID 0x2341:0x0043
if(dev_handle == NULL){
printf("ERROR OPENING!");
return -1;
}
else{
printf("UNO OPENED!\n");
}
libusb_free_device_list(devs, 1);
libusb_reset_device(dev_handle);
if(libusb_set_configuration(dev_handle,1)<0){
printf("SET CONFIG ERROR!\n");
}
for(int k=0;k<2;++k){
if(libusb_kernel_driver_active(dev_handle, k) == 1) {
printf("KERNEL DRIVER ACTIVE:INTERFACE %d\n",k);
if(libusb_detach_kernel_driver(dev_handle, k) != 0){
printf("ERROR KERNEL DETACH:INTERFACE %d\n",k);
return -1;
}
}
if(libusb_claim_interface(dev_handle, k)<0){
printf("ERROR CLAM INTERFACE %d!\n",k);
return -1;
}
printf("INTERFACE %d CLAMED!\n",k);
}
return 0;
}
The Arduino sketch is also attached here.
unsigned char buff[] = {0, 0, 0, 0};
void setup() {
Serial.begin(9600);
while (!Serial){
;
}
Serial.setTimeout(5000);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {}
void serialEvent() {
if (Serial.available() >= 4) {
Serial.readBytes(buff, 4);
if ((buff[0] == 65) && (buff[1] == 71) && (buff[2] == 67) && (buff[3] == 68)) {
Serial.write(buff,4);
Serial.flush();
digitalWrite(LED_BUILTIN, HIGH);
buff[0]=buff[1]=buff[2]=buff[3]=0x0;
delay(500);
}
digitalWrite(LED_BUILTIN, LOW);
}
}
The Compiler output is attached here
g++ -Wall -fPIC -Wextra -Werror -pedantic -pedantic-errors -O3 -I. -o UNOTEST UNOTest_2.cpp -L/home/mkovash/sis3153/libUSB1Driver/libusb-1.0.23/exports/lib -Bstatic -lusb-1.0
In file included from UNOTest_2.cpp:1:0:
libusb.h:741:46: error: ISO C++ forbids zero-size array ‘dev_capability_data’ [-Wpedantic]
uint8_t dev_capability_data[ZERO_SIZED_ARRAY];
^
libusb.h:766:78: error: ISO C++ forbids zero-size array ‘dev_capability’ [-Wpedantic]
struct libusb_bos_dev_capability_descriptor *dev_capability[ZERO_SIZED_ARRAY];
^
libusb.h:1259:70: error: ISO C++ forbids zero-size array ‘iso_packet_desc’ [-Wpedantic]
struct libusb_iso_packet_descriptor iso_packet_desc[ZERO_SIZED_ARRAY];
^
UNOTest_2.cpp: In function ‘int main()’:
UNOTest_2.cpp:48:9: error: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Werror=unused-result]
scanf("%u",&character);
~~~~~^~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors