Printing 印刷垃圾

Printing 印刷垃圾,printing,arduino,Printing,Arduino,我正在编写一些代码,通过SPI记录来自多个传感器的电压测量值。我将所有数据保存在自定义数据结构中,然后在发生太多事件或用户请求数据时将数据结构打印到终端。我发现的问题是,当我调用DataDump函数时,每个事件中的最后一个数据值都是完全错误的。如果我尝试在记录数据后立即打印数据,它是正确的。我把我认为重要的代码放在下面,但这里是整个程序的链接 我唯一想知道的是,当我为200个事件分配内存时,结构的范围不会扩展到dumpData函数。但这并没有真正意义,因为所有其他数据都是正确的。我的另一个想法是

我正在编写一些代码,通过SPI记录来自多个传感器的电压测量值。我将所有数据保存在自定义数据结构中,然后在发生太多事件或用户请求数据时将数据结构打印到终端。我发现的问题是,当我调用DataDump函数时,每个事件中的最后一个数据值都是完全错误的。如果我尝试在记录数据后立即打印数据,它是正确的。我把我认为重要的代码放在下面,但这里是整个程序的链接

我唯一想知道的是,当我为200个事件分配内存时,结构的范围不会扩展到dumpData函数。但这并没有真正意义,因为所有其他数据都是正确的。我的另一个想法是,当从char->Binary->decimal转换时会出现错误,但同样地,只有单个值是错误的

第一段代码是我创建的一个数据结构,用于处理来自多个传感器的数据。数据只是来自ADC的8位SPI数据,所以我使用了无符号字符来最小化内存使用量。我还为200个事件分配了足够的内存

typedef struct                //event structure, containts a timestamp element and an array of 18 data points
{
  unsigned long int timeStamp;
  unsigned char data[SENSORS];
} Event;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Event eventLog[MAX_DATA];        //an array of structures representing 200 events, once the 200 events have been filled the data will be printed
在Main“loop()”中,当管脚处于高位时,会有一个数据收集过程。当偶数发生时,第一个事件数据结构将记录一个时间戳,然后是开始模拟到数字转换并将数据存储在当前事件的数据阵列中的过程

eventLog[i].timeStamp = micros();

    for (j=0; j<=SENSORS; ++j) {
      lockAndPop();                         //lock digital value and reset conversion
      selector = inputSelector(selector);      //increment the selector pin
      PORTA = selector;
      digitalWrite(RD, LOW);                //Start new conversion

      digitalWrite(CLK_INH, LOW);                //Start the data transfer
      eventLog[i].data[j] = SPI.transfer(0);     //read a single byte from the SPI line
      digitalWrite(CLK_INH, HIGH);              //Inhibit clock
      digitalWrite(LD, LOW);
      while(digitalRead(INT1)){}                //wait for previous conversion to end            
      } 
    i++;
当ADC读取参考电压时,最后一个值应保持恒定,就像之前的三个值一样。打印时数据完全有效

Serial.println(eventLog[i].data[3])
从主“loop()”代码。我尝试过从数据转储函数运行相同的代码,但仍然收到垃圾。此外,我还使用逻辑分析仪监控SPI线路,并在数据线路上看到应该显示的数据


**我唯一想知道的是,当我为200个事件分配内存时,结构的范围不会扩展到dumpData函数。但这并没有真正意义,因为所有其他数据都存在**

一开始我没有意识到,但一旦你回答了我的问题,我的问题就突出出来了

如果
传感器
等于三,则
无符号字符数据[传感器]是由三个元素组成的数组。不是你期望的四个

数组与从零开始的索引(0,1,2,3,…)一起使用,但是在声明它们时,需要输入所需元素的实际计数

为了解决这个问题,我将
传感器设置为等于四个,然后将循环从零调整到小于
传感器(不小于或等于)。这同样适用于
MAX_DATA
。循环使用的元素比实际拥有的元素多一个

除非您需要索引,否则C++11具有防止数组溢出的功能。这是循环的范围

您现在使用的循环:

for (localCount = 0; localCount<=eventCount; ++localCount){
  pos += sprintf(pos, "%lu", eventLog[localCount].timeStamp);          //sprintf will append the data to the pointer "pos", and return the number of byte append.
  for (localData = 0; localData<=SENSORS; ++localData){
     pos += sprintf(pos, " %d", (unsigned int)(eventLog[localCount].data[localData]));   
  }
  Serial.println(buf);
  pos = base;
}
由于没有涉及索引,因此始终使用实际的元素数。范围循环一开始可能很混乱,但非常有用


修复
传感器
MAX_DATA
的使用可能无法解决所有问题,但是,如果问题仍然存在,我们可以解决其余问题。如果还有更多问题,请在下面的评论中留下一些信息,我会更新我的答案。

您使用的是哪种板?传感器的值是多少?传感器=3,所以我希望有4个读数。我使用的是mega 2560,因此,如果我在写入eventLog[I].data[3]时正确理解了这一点,那么我很可能是在写入eventLog[I+1].timeStamp的地址。这就是为什么当我试图打印eventLog[I].data[3]时,它可以工作,但下一次迭代会用下一个事件的时间戳重写数据?我会试一试,然后让你知道。马上!我已经找了一段时间了。
Serial.println(eventLog[i].data[3])
for (localCount = 0; localCount<=eventCount; ++localCount){
  pos += sprintf(pos, "%lu", eventLog[localCount].timeStamp);          //sprintf will append the data to the pointer "pos", and return the number of byte append.
  for (localData = 0; localData<=SENSORS; ++localData){
     pos += sprintf(pos, " %d", (unsigned int)(eventLog[localCount].data[localData]));   
  }
  Serial.println(buf);
  pos = base;
}
for( auto &entry : eventLog ){
  pos += sprintf(pos, "%lu", entry.timeStamp); 
  for( char reading : entry.data ){
    pos += sprintf(pos, " %d", (unsigned int)reading);
  }
  Serial.println(buf);
  pos = base;
}