采集端的主要功能与监控端大同小异不过多赘述,主要讲不同的地方。
监控端的功能采集端也都要有,而相对于监控端采集端要加入与arduino的串口通信部分以及多一个采集线程。
故在MainWindow类中额外要定义一个线程对象
ThreadSensor SensorCollector;
且于构造函数中初始化时启动该线程且连接槽函数与信号
connect(&(this->SensorCollector),SIGNAL(Collected(int)),this,SLOT(DelCollection(int)));
SensorCollector.start();
#define DHT11_PIN 0
byte read_dht11_dat()
{
byte i=0;
byte result=0;
for(i=0;i<8;i++)
{
while(!(PINC & _BV(DHT11_PIN)));
delayMicroseconds(30);
if(PINC & _BV(DHT11_PIN))
result |=(1<<(7-i));
while((PINC &_BV(DHT11_PIN)));
}
return result;
}
void setup()
{
DDRC |=_BV(DHT11_PIN);
PORTC |=_BV(DHT11_PIN);
Serial.begin(9600);
}
void loop()
{
byte dht11_dat[5];
byte dht11_in;
byte i;
PORTC &=~ _BV(DHT11_PIN);
delay(18);
PORTC |=_BV(DHT11_PIN);
delayMicroseconds(40);
DDRC &=~_BV(DHT11_PIN);
delayMicroseconds(40);
dht11_in = PINC & _BV(DHT11_PIN);
if(dht11_in)
{
return;
}
delayMicroseconds(80);
dht11_in = PINC & _BV(DHT11_PIN);
if(!dht11_in)
{
return;
}
delayMicroseconds(80);
for(i=0;i<5;i++)
dht11_dat[i] = read_dht11_dat();
DDRC |=_BV(DHT11_PIN);
PORTC |=_BV(DHT11_PIN);
byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];
if(dht11_dat[4]!=dht11_check_sum)
{
}
Serial.println(dht11_dat[2],DEC);
delay(5000);
}
class ThreadSensor : public QThread
{
Q_OBJECT
public:
ThreadSensor();
void stop();
protected:
void run();
void startSensor();
signals:
void Collected(int num);
private:
volatile bool stopped;
int dev_res = 0;
int dev_Id;
};
开始采集函数StartSensor,在run函数中调用
void ThreadSensor::startSensor()
{
char buff[4];
int len;
long g_curr_offset = 1;
FILE *fp = fopen("/dev/ttyACM0","w+");
if (!fp)
{
printf("cant open file, file\n");
return ;
}
fseek(fp, g_curr_offset, SEEK_SET);
while(!feof(fp))
{
memset(buff, 0x0, FILE_LINE_LEN);
fgets(buff,4, fp);
len = strlen(buff);
buff[len - 1] = 0;
g_curr_offset += len;
int num = atoi(buff);
char property_payload[30] = {0};
HAL_Snprintf(property_payload, sizeof(property_payload), "{\"Temp\": %d}", num);
if(num!=0)
{
IOT_Linkkit_Report(dev_Id,ITM_MSG_POST_PROPERTY,(unsigned char*)property_payload,strlen(property_payload));
emit Collected(num);
sleep(1);
IOT_Linkkit_Yield(200);
}
}
fclose(fp);
return ;
}
采集到数据后先通过IOT_Linkkit_Report函数发送至云端属性物模型中,更新设备状态,之后再emit Collected,发送采集信号给主线程,这边加了个不等于0的判断条件,是因为读取的时候可能由于读的大小不对会有0数据出现,故这里去掉错误数据。
主线程对应槽函数:
void MainWindow::DelCollection(int n)
{
char inttemp[100];
int ntemp = n;
sprintf(inttemp,"%d",ntemp);
ui->Temperature->setText(inttemp);
publish_to_cloud(new_entry("Temperature",inttemp,""));
}