我是 Arduino 新手。我正在尝试学习如何使用通过 USB 接收数据,但它不起作用。
这是我的代码:
struct arrayData{
char* array;
int size;
};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
//Create struct
struct arrayData* myStruct = (arrayData*) errorHandling(malloc(sizeof(arrayData)));
if(myStruct == NULL) return;
myStruct -> size = 0;
myStruct -> array = (char*) errorHandling(malloc(sizeof(char)));
if(myStruct -> array == NULL) return;
myStruct -> array[0] = '\0';
// Read serial input buffer
myStruct = readBuffer(myStruct);
if(myStruct == NULL) return;
// Print each byte
for(int i = 0;i < myStruct -> size;i++){
Serial.print(myStruct -> array[i]);
}
// Free
free(myStruct -> array);
myStruct -> array = NULL;
free(myStruct);
myStruct = NULL;
}
arrayData* readBuffer(arrayData* arrayMeta){
// NOT RECOMMENDED!! abstracted malloc may cause mem leak
// If array is NULL create it
if(arrayMeta -> array == NULL){
arrayMeta -> array = (char*) errorHandling(malloc(sizeof(char)));
if(arrayMeta -> array == NULL) return NULL;
arrayMeta -> size = 1;
}
// If Serial input buffer is not empty read
if(Serial.available() > 0){
char byte = Serial.read();
int x = 0;
// While buffer is not empty and we have not recieved end of transmission
while(byte != '\n' && Serial.available() > 0){
// Make array the right size
arrayMeta -> array = (char*) errorHandling(realloc(arrayMeta -> array, (x+1) * sizeof(char)));
if(arrayMeta -> array == NULL) return NULL;
// Update the size member of struct
arrayMeta -> size = x+1;
// Write into array
arrayMeta -> array[x] = byte;
// Read next byte
byte = Serial.read();
x++;
}
}
return arrayMeta;
}
// Return ptr on success and NULL on failure
void* errorHandling(void* ptr){
if(ptr == NULL){
Serial.println("Malloc failed");
return NULL;
}
return ptr;
}
我有一种感觉,这与释放内存或类似的东西有关,因为当我乱搞时,我输入了“ggggg”,它输出了:
gggg
gggg
gg
gg
g
但是现在代码略有不同,我无法重现它。
此外,当我将
Serial.println();
放在 for 循环之后时,会打印一些随机字符,然后它只是大量换行符。
编辑: 我做了一些更改和以下工作,但随机字符有时不会打印,我不明白为什么。 例如,输入“qwerty”有时会打印 qwety 或 qwery 或 qwert 或 qert。
#define PERFORMANCE 10
struct arrayData{
char* array;
int size;
};
struct arrayData* myStruct;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
//Create struct
myStruct = (arrayData*) errorHandling(malloc(sizeof(arrayData)),'0');
if(myStruct == NULL) return;
myStruct->size = 0;
myStruct->array= NULL;
}
void loop() {
// put your main code here, to run repeatedly:
// Read serial input buffer
myStruct = readBuffer(myStruct);
if(myStruct == NULL) return;
// Print each byte
if(myStruct->array != NULL){
for(int i = 0;i < myStruct->size;i++){
Serial.print(myStruct->array[i]);
}
}
// Free
free(myStruct->array);
myStruct->array = NULL;
}
arrayData* readBuffer(arrayData* arrayMeta){
// NOT RECOMMENDED!! abstracted malloc may cause mem leak
// If array is NULL create it
if(arrayMeta->array == NULL && Serial.available() > 0){
arrayMeta->array = (char*) errorHandling(malloc(sizeof(char)),'2');
if(arrayMeta->array == NULL) return NULL;
arrayMeta->size = 1;
}
// If Serial input buffer is not empty read
if(Serial.available() > 0){
char byte;
int x = 0;
// While buffer is not empty and we have not recieved end of transmission
while(Serial.available() > 0){
// Read next byte
byte = Serial.read();
if (byte == '\n') break;
// Make array the right size
if(arrayMeta->size == x){
arrayMeta->array = (char*) errorHandling(realloc(arrayMeta->array, (x + PERFORMANCE) * sizeof(char)),'3');
if(arrayMeta->array == NULL) return NULL;
// Update the size member of struct
arrayMeta->size++;
}
// Write into array
arrayMeta->array[x] = byte;
x++;
}
if(arrayMeta->size != x){
arrayMeta->array = (char*) errorHandling(realloc(arrayMeta->array, (x) * sizeof(char)),'4');
if(arrayMeta->array == NULL) return NULL;
// Update the size member of struct
arrayMeta->size = x;
}
}
return arrayMeta;
}
// Return ptr on success and NULL on failure
void* errorHandling(void* ptr, char error){
if(ptr == NULL){
Serial.println("Malloc failed, error:");
Serial.println(error);
return NULL;
}
return ptr;
}
@Juraj 发送了一个有用的链接,告诉我需要做什么才能让它工作。
我需要在 while 循环中添加
delay(10)
,因为我需要等待字节进入,然后再检查是否还有剩余。发生的情况是 readBuffer()
函数将被调用,并且只读取 1 个字符,然后 Serial.available()
将返回 0,因为我没有给下一个字节发送足够的时间。