Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在单独的else语句中修改字符数组时,为什么此函数不返回值1?_C_Arduino - Fatal编程技术网

C 在单独的else语句中修改字符数组时,为什么此函数不返回值1?

C 在单独的else语句中修改字符数组时,为什么此函数不返回值1?,c,arduino,C,Arduino,首先,在我解释发生了什么之前,让我向您展示我的代码: #include <SoftwareSerial.h> //Strings char inData[20]; //Allocate some space for the string char inChar; //Where to store the character read byte index = 0; //Index into array; where to store the character void setu

首先,在我解释发生了什么之前,让我向您展示我的代码:

#include <SoftwareSerial.h>

//Strings
char inData[20]; //Allocate some space for the string
char inChar; //Where to store the character read
byte index = 0; //Index into array; where to store the character

void setup()
{
  //Begin Serial Communication
  Serial.begin(9600);
}

void loop(void){

  //Determine if command mode should be entered
  if(Comp("BTMODIFY") == 0)
  {
     Serial.print("Entering bluetooth command mode...); 
  }
}

char Comp(char* input){
  //Internal variables
  int i = 0;

  while(Serial.available() > 0) //Don't read unless you know there is data
  {
    if(index < 19) //One less than the size of the array
    {
      inChar = Serial.read(); //Read a character
      inData[index] = inChar; //Store it
      index++; //Increment where to write next
      inData[index] = '\0'; //Null terminate the string
    }
   }

  if(strcmp(inData, input) == 0){
    index = 0;
    inData[index] = '\0';
    return(0);
  }

  else{
    index = 0;
    inData[index] = '\0';
    return(1);
  }
}
然后代码正常工作,这意味着当我键入“BTMODIFY”时,终端上会打印一条语句。由于代码是现在的,没有发生任何事情-这意味着
if(Comp(“BTMODIFY”)==0)
永远不会计算为true。很明显,我遗漏了一些东西

其思想是重用变量
inData
,因此我只是在字符串的开头放置一个空终止符


任何建设性的输入都值得赞赏。

程序可能陷入无限循环:

  while(Serial.available() > 0) //Don't read unless you know there is data
  {
    if(index < 19) //One less than the size of the array
    {
      inChar = Serial.read(); //Read a character
      ...
    }
  }
或者,您可以重写Comp函数:

int Comp(char* input) {
  //Internal variables
  int i = 0;

  int curr = 0;
  while(Serial.available() > 0) //Don't read unless you know there is data
  {
    if(index < 19) //One less than the size of the array
    {
      inChar = Serial.read(); //Read a character
      if(input[curr] == '\0') return 0; // Input ended, but data is still there.
      if(input[curr++] != inChar) return 0; // Data doesn't match.
    }
    else return 1;  // Data matches.
   }

   return 1;  // Data matches.
}
int Comp(字符*输入){
//内部变量
int i=0;
int curr=0;
while(Serial.available()>0)//除非知道有数据,否则不要读取
{
if(index<19)//比数组的大小小一个
{
inChar=Serial.read();//读取字符
if(input[curr]=='\0')返回0;//输入结束,但数据仍然存在。
如果(输入[curr++]!=inChar)返回0;//数据不匹配。
}
else返回1;//数据匹配。
}
返回1;//数据匹配。
}

我认为这可能与阅读速度和执行函数的速度有关。下面是一段完全未经测试且未编译的代码,我认为(希望)它能满足您的需求

#include <SoftwareSerial.h>

#define MAXLEN 20

char getline(char* unsigned int);

void setup()
{
  //Begin Serial Communication
  Serial.begin(9600);
}

void loop(void){

  //Determine if command mode should be entered
  char cmd[MAXLEN];
  while (!getline(cmd, MAXLEN))
      ; // Wait for a complete input line

  if(strcmp("BTMODIFY", cmd) == 0)
  {
     Serial.print("Entering bluetooth command mode..."); 
  }
}

char getline(char* input, unsigned int size){
  static unsigned int i = 0;
  static char done = 0;

  while(Serial.available() > 0
          && i < size-1
          && !done)
  {
    char c = Serial.read(); //Read a character
    input[i++] = c;         //Store it and increment
    if (c == '\n')          //Or whatever newline your serial terminal is sending
    {
        done = 1;
    }
  }
  input[i] = '\0';

  if (done)
  {
    done = 0;
    return 0;
  }

  return 1;
}
#包括
#定义MAXLEN 20
char getline(char*无符号整数);
无效设置()
{
//开始串行通信
Serial.begin(9600);
}
无效循环(无效){
//确定是否应进入命令模式
char cmd[MAXLEN];
而(!getline(cmd,MAXLEN))
;//等待完整的输入行
如果(strcmp(“BTMODIFY”,cmd)==0)
{
串行打印(“进入蓝牙命令模式…”);
}
}
char getline(char*输入,无符号整数大小){
静态无符号整数i=0;
静态字符完成=0;
而(Serial.available()>0
&&i<1号
&&!完成)
{
char c=Serial.read();//读取一个字符
输入[i++]=c;//存储并递增
如果(c=='\n')//或串行终端正在发送的任何新行
{
完成=1;
}
}
输入[i]='\0';
如果(完成)
{
完成=0;
返回0;
}
返回1;
}
Comp()
在数据到达时被多次调用

Serial.available()

如果
Serial.available()。下一次调用
Serial.available()
很容易返回0,因为此代码比数据到达的速度快得多。当
else
块就位时,计数再次为零

如果没有
else
块,数据有可能1)在
inData
中累积并匹配
“BTMODIFY”
或2)填充缓冲区,不再匹配

关键的逻辑错误是假设数据一次到达串行接口,而不是在
char
之间存在潜在的大时间间隔(从CPU的角度来看)

建议的更改:
1) 当缓冲区已满时,清空最老的
字符
。将
inData
视为先进先出。
2) 在每个
字符之后测试是否匹配
3) 避免使用像19这样的幻数-使用的派生值

char Comp(const char* input) {
  size_t len = strlen(input);
  int i = 0;
  while(Serial.available() > 0) {
    if (index > (sizeof inData - 2)) {
      // toss eldest `char`
      index = sizeof inData - 2;
      memmove(&inData[0], &inData[1], index);
    }
    inChar = Serial.read(); //Read a character
    inData[index] = inChar; //Store it
    index++; //Increment where to write next
    inData[index] = '\0'; //Null terminate the string  **

    if(index >= len && memcmp(&inData[index-len], input, len) == 0) {
      index = 0;
      inData[index] = '\0'; // **
      return(0);
    }
  }
  return(1);
}

**这些步骤是不需要的,
inData
的大小可能是19。我同意,这很有趣。它似乎创建了一个无限循环,因为当未调用
Serial.read()
时,数据被推出缓冲区。但是,它不起作用。如果数据被截断,那么下面的
if
语句:
(strcmp(inData,input)==0)
将不为真。使用
strncmp
。我理解你的意思,但解决方案似乎不符合我所经历的症状。如果我在原始else块中对
return(1)
之前的两条语句进行注释,则代码的行为与我预期的一样(打印出一条语句-没有无限循环)。然而,一旦我把这两行代码加进去,它就会停止工作(没有打印出来)。我无法解决您的问题。但是,您可以尝试更改
Comp
功能,看看它是否有效。(只需删除整个该死的bug!)如果您在串行终端中输入BTMODIFY,则可能是您实际在程序中输入了“BTMODIFY\n”。您是对的。根据终端设置,我正在发送一个清除和一个新线信号以及字符串。然而,到目前为止,这似乎还没有造成问题。唯一的问题是我的else语句中的两行;inData[index]='\0'
使我认为您的函数读取串行数据的速度比可用的速度快。尝试更改为
while(Serial.available()>8
或类似的功能。但是,如果读入速度不够快,您可能会遇到换行符的问题。有趣的想法。我已经删除了换行符(在HC-05蓝牙芯片上使用AT命令的剩余部分),并将尝试一下。
#include <SoftwareSerial.h>

#define MAXLEN 20

char getline(char* unsigned int);

void setup()
{
  //Begin Serial Communication
  Serial.begin(9600);
}

void loop(void){

  //Determine if command mode should be entered
  char cmd[MAXLEN];
  while (!getline(cmd, MAXLEN))
      ; // Wait for a complete input line

  if(strcmp("BTMODIFY", cmd) == 0)
  {
     Serial.print("Entering bluetooth command mode..."); 
  }
}

char getline(char* input, unsigned int size){
  static unsigned int i = 0;
  static char done = 0;

  while(Serial.available() > 0
          && i < size-1
          && !done)
  {
    char c = Serial.read(); //Read a character
    input[i++] = c;         //Store it and increment
    if (c == '\n')          //Or whatever newline your serial terminal is sending
    {
        done = 1;
    }
  }
  input[i] = '\0';

  if (done)
  {
    done = 0;
    return 0;
  }

  return 1;
}
char Comp(const char* input) {
  size_t len = strlen(input);
  int i = 0;
  while(Serial.available() > 0) {
    if (index > (sizeof inData - 2)) {
      // toss eldest `char`
      index = sizeof inData - 2;
      memmove(&inData[0], &inData[1], index);
    }
    inChar = Serial.read(); //Read a character
    inData[index] = inChar; //Store it
    index++; //Increment where to write next
    inData[index] = '\0'; //Null terminate the string  **

    if(index >= len && memcmp(&inData[index-len], input, len) == 0) {
      index = 0;
      inData[index] = '\0'; // **
      return(0);
    }
  }
  return(1);
}