首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ATtiny写入值错误的数组

ATtiny写入值错误的数组
EN

Stack Overflow用户
提问于 2018-01-31 14:59:41
回答 2查看 271关注 0票数 1

这是我的第一个问题,我希望我没有踩到任何人的拖曳物:-)

目前,我正在为我的电动踏板车开发一个模块化的电池管理系统,它以ATtiny85为主,多ATtiny85为从。每个从单元都在监视一个单元(或多个单元并行的数组),并且还使用这个单元给自己供电。为了安全起见,它读取电池的电压并读取该电池的温度传感器。它通过一个独立的I2C总线将这两个信息发送给主机,主主机将对其进行分析,如果该单元应该激活平衡或不激活,则最终将发送一个响应。

为此,我使用digispark引导程序,并使用USB显示软件。我正在用Arduino IDE编程的软件本身。

到目前为止,我成功地在使用TinyWireS的从服务器和使用TinyWireM的主服务器之间建立了良好的连接。我成功地从多个奴隶发送数据给主人,反之亦然。

但是,当我从总线上删除一个或多个奴隶时,读取例程将用以前接收到的数据填充未接收的数据,并且不会写空行或零。

下面是相关的例程,我在其中轮询奴隶地址,然后单独向每个从站询问4个字节的有效负载。从站将测量的电压和温度分离为两个字节,并将结果4个字节分别发送到I2C总线上。

主机将接收这4个不同的字节,并将它们再次组合到电压和温度,并将它们写入一个与其单元号匹配的位置上的数组中。

代码语言:javascript
复制
for (int cell_num = 1; cell_num <= CELL_COUNT; cell_num++)  //poll data from all cells, start with cell 1 to max
  {
    int slave_add = 0x3F+cell_num;        //connect to cell, adress offset 0x3F, first cell is 0x40
    v_data[cell_num] = 0;
    t_data[cell_num] = 0;
    TinyWireM.requestFrom(slave_add, 4);  //request from selected cell 4 bytes
    while(TinyWireM.available())
    {
      v_low = TinyWireM.receive();   //read first byte as low byte of voltage
      v_high = TinyWireM.receive();  //read second byte as hight byte of voltage
      t_low = TinyWireM.receive();   //read third byte as low byte of temp
      t_high = TinyWireM.receive();  //read fourth byte as hight byte of temp

      v_data[cell_num] = 0;
      t_data[cell_num] = 0;

      v_data[cell_num] = (v_high<<8) | v_low;  //shift high byte of voltage and combine with low byte
      t_data[cell_num] = (t_high<<8) | t_low;  //shift high byte of temp and combine with low Byte

      v_high = 0;
      v_low = 0;
      t_high = 0;
      t_low = 0;
    }

一个演示错误的小例子:在总线上应该是14个从站(CELL_COUNT = 14),一个或多个从站(比方说5号和6号)有一个错误,并且没有发送这4个字节。所以主程序在一个小的OLED显示器上显示从站的所有数据。母版没有在第5行和第6行显示0,而是显示数字4的相同值。

显示的前半部分如下所示:

4125

4035

4156

四千一百三十七

4137

4137

4089

此外,您还可以在下面找到完整的代码:

代码语言:javascript
复制
//1MHz Speed!!!!

#include <TinyWireM.h>
#include "SSD1306_minimal.h"

#define CELL_COUNT 14 //from 1 to cell amout, number of cells on bus
SSD1306_Mini oled;

uint16_t v_data[CELL_COUNT];
uint16_t v_data_max = 0;
uint16_t t_data[CELL_COUNT];
uint16_t t_data_max = 0;
char cast1[8] = {};
char cast2[8] = {};
uint8_t v_low;
uint8_t v_high;
uint8_t t_low;
uint8_t t_high;

void setup()
{
  pinMode(1, OUTPUT);     //led pinset digispark
  digitalWrite(1, LOW);   //disable led
  oled.init(0x3c);        //init oled adress 0x3c
  oled.clear();           //clear oled display
  oled.startScreen();     //start oled routine to write
  TinyWireM.begin();      //start i2c lib for com
}

void loop()
{
  v_data_max = 0;
  t_data_max = 0;

  //read received data
  for (int cell_num = 1; cell_num <= CELL_COUNT; cell_num++)  //poll data from all cells, start with cell 1 to max
  {
    int slave_add = 0x3F+cell_num;        //connect to cell, adress offset 0x3F, first cell is 0x40
    v_data[cell_num] = 0;
    t_data[cell_num] = 0;
    TinyWireM.requestFrom(slave_add, 4);  //request from selected cell 4 bytes
    while(TinyWireM.available())
    {
      v_low = TinyWireM.receive();   //read first byte as low byte of voltage
      v_high = TinyWireM.receive();  //read second byte as hight byte of voltage
      t_low = TinyWireM.receive();   //read third byte as low byte of temp
      t_high = TinyWireM.receive();  //read fourth byte as hight byte of temp

      v_data[cell_num] = 0;
      t_data[cell_num] = 0;

      v_data[cell_num] = (v_high<<8) | v_low;  //shift high byte of voltage and combine with low byte
      t_data[cell_num] = (t_high<<8) | t_low;  //shift high byte of temp and combine with low Byte

      v_high = 0;
      v_low = 0;
      t_high = 0;
      t_low = 0;
    }
  }

  for (int cell_num = 1; cell_num <= CELL_COUNT; cell_num++)  //pring voltage and temp data to oled
  {
    oled.startScreen();   //start oled routine to write
    if (cell_num<=7)      //check if first half of cells (cell number = 14) or second half
    {
      oled.cursorTo(0,cell_num-1);  //jump to right line for cell
    }
    else
    {
      oled.cursorTo(66,cell_num-8);  //jump to right line for cell
    }
    oled.printString(itoa(v_data[cell_num], cast1, 10));  //change data from int to str and print on oled
    oled.startScreen();
    if (cell_num<=7)
    {
      oled.cursorTo(30,cell_num-1);  //jump to right line for cell
    }
    else
    {
      oled.cursorTo(96,cell_num-8);  //jump to right line for cell
    }
    oled.printString(itoa(t_data[cell_num], cast2, 10));  //change data from int to str and print on oled
  }

  delay(5000);
  oled.cursorTo(0,0);
  oled.clear();
}

我希望有人能指出正确的方向来解决这个问题.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-05 12:21:37

我在lib TinyWireM中发现了一些不便。如果收到一些数据,库将将其存储在缓冲区中。如果您读取缓冲区,它将显示内容。如果没有收到新的数据,缓冲区将保持原样,如果再次读取缓冲区,您将读取完全相同的数据。

为此,我更改了TinyWireM.ccp,以便如果读取一次,缓冲区将被删除。

现在,如果您再次读取缓冲区而没有新的接收数据,它将显示0。

票数 0
EN

Stack Overflow用户

发布于 2018-01-31 21:59:30

我缩小了一点.在下面的代码中,如果没有收到新的数据,函数TinyWireM将从循环中将数据写入变量v_high、v_low、T_high和t_low。但令人毛骨悚然的是,它们并不都是平等的,它们在循环之前都有完全相同的值。所以v_high (old) = v_high (new)等等。

如果它们都是使用相同的函数设置的,而函数应该运行4次,那么每个变量运行一次,这又怎么可能呢?

以下是有关部分:

代码语言:javascript
复制
v_low = TinyWireM.receive();   //read first byte as low byte of voltage
v_high = TinyWireM.receive();  //read second byte as hight byte of voltage
t_low = TinyWireM.receive();   //read third byte as low byte of temp
t_high = TinyWireM.receive();  //read fourth byte as hight byte of temp
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48545175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档