I’m writing a c++ program based on libusb-1.0 library to communicate with an Arduino UNO. I have uploaded a sketch to the UNO, which would transmit a sequence of bytes upon receiving 4 bytes from the computer. The sketch works as intended. I checked it with the serial monitor.
void setup() {
Serial.begin(9600);
while (!Serial) {
;
}
}
char buff[]={0,0,0,0};
void loop() {
if(Serial.available()>=4){
Serial.readBytes(buff,4);
Serial.print('A');
Serial.print('B');
Serial.print('C');
Serial.print('D');
Serial.print('E');
}
delay(300);
}
**But the C++ program doesn’t receive the complete byte sequence. ** Most of the time it receives a fraction of the sequence like AB or ABC or A.
here is the C++ code. it works fine except for the missing bytes. Did anybody successfully used libusb alone with Arduino broads to write custom made applications. Did anybody encounter a similar problem?
#include "libusb.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static const int ENDPOINT_IN = 0x83;
static const int ENDPOINT_OUT = 0x04;
static const int USB_TIMEOUT = 10000;
libusb_device_handle *dev_handle=NULL;
libusb_context *ctx = NULL;
int OPEN_DEVICE();
int CLOSE_DEVICE();
int main(){
if(OPEN_DEVICE()<0){
CLOSE_DEVICE();
return -1;
}
usleep(3000000);
unsigned char encoding[] = {0x80,0x25,0x00, 0x00, 0x00, 0x00, 0x08 }; //9600 1N8
int 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]={65,66,67,68};
unsigned char iUsbBuf[64];
int nBytes=0;
int status =-1;
unsigned char character=0;
while(1){
printf("send byte:");
scanf("%u",&character);
if(character==255){
break;
}else{
//cUsbBuf[0] = character;
}
status = libusb_bulk_transfer(dev_handle, (ENDPOINT_OUT|LIBUSB_ENDPOINT_OUT),cUsbBuf,4,&nBytes, USB_TIMEOUT);
if(status<0){
printf("TRANSFER ERROR:%s\n",libusb_error_name(status));
}
printf("out Bytes:%d\n",nBytes);
usleep(2000000);
status = libusb_bulk_transfer(dev_handle,(ENDPOINT_IN|LIBUSB_ENDPOINT_IN),iUsbBuf,5,&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<5;++i){
printf("%d ", iUsbBuf[i]);
iUsbBuf[i]=0;
}
printf("\n\n\n");
nBytes=0;
}
CLOSE_DEVICE();
return 0;
}
int OPEN_DEVICE(){
libusb_device **devs;
if(libusb_init(&ctx)<0){
printf("ERROR INIT!");
return -1;
}
libusb_get_device_list(ctx, &devs);
dev_handle = libusb_open_device_with_vid_pid(ctx,0x2341,0x0043);
if(dev_handle == NULL){
printf("ERROR OPENING!");
return -1;
}
else{
printf("UNO OPENED!\n");
}
libusb_free_device_list(devs, 1);
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_set_configuration(dev_handle,1)<0){
printf("SET CONFIG ERROR!\n");
}
usleep(1000000);
for(int k=0;k<2;++k){
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;
}
int CLOSE_DEVICE(){
if(libusb_release_interface(dev_handle, 0)!=0){ //release the claimed interface
printf("Err releasing!");
return -1;
}
if(libusb_release_interface(dev_handle, 1)!=0){ //release the claimed interface
printf("Err releasing!");
return -1;
}
libusb_close(dev_handle);
libusb_exit(ctx);
return 0;
}
I understand the same outcome can be achieved using the linux serial library. I would still pursue this because I’m curious to know what cause this anomalous behaviour.