基本ライブラリ
デジタルIO
アナログIO
拡張IO
時間
数学
三角関数
乱数
ビットバイト操作
割り込み
シリアル通信
標準ライブラリ
Ethernet
サーボモーター
ステッピングモーター
キャラクタ液晶表示
SPI通信
I2C通信(Wire)
SD
SD(File操作)
周期処理(MsTimer2)
時計(RTC)
PPG(パルス生成)
WiFiEsp
ICS(シリアルサーボ)
FreeRTOS Tips
FreeRTOS キュー
キューはタスク同士のデータ通信に使用します。キューはサイズが決められたFIFOバッファと同様です。基本的にFIFOですが、先頭のバッファにデータを上書きすることもできます。
また、キューは複数のタスクによる書き込み、そして読み込みが可能です。
それではキューを用いたシンプルな例を示します。
#include <Arduino.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
QueueHandle_t queue1;
void sender_task(void *pvParameters);
void setup(){
Serial.begin(9600);
delay(3000); // wait for display serial monitor
queue1 = xQueueCreate(1, sizeof(uint32_t));
xTaskCreate(sender_task, "SENDER", 512, NULL, 4, NULL );
}
void loop(){
uint32_t buf;
xQueueReceive(queue1, &buf, 0);
Serial.println(buf);
delay(1000);
}
void sender_task(void *pvParameters){
uint32_t count = 0;
while(1){
xQueueSend(queue1, &count, 0);
count++;
delay(100);
}
}
出力結果:
0
11
21
31
41
サンプルでは、まずsetupで長さが1のキュー"queue1"を生成しています。長さは1ですが、実際にはuint32_tのサイズである4バイトのキューです。その後、タスク"sender_task"が生成され、100ms間隔でインクリメントするcount値をキューに送ります。loopの中で1秒ごとにキューからデータを読み込んで表示します。
出力結果として、count初期値の0が出力されています。これはキューが上書きされず、loopでxQueueReceiveが行われるまで保持していることを意味します。
なお、xQueueSendやxQueueReceiveは第3引数の値によって、キューが空く、あるいはキューにデータが来るまで一定時間待つという設定を行うことができます。
xQueueSendをxQueueOverwriteに置き換えると、キューにデータを上書きするようになります。例えばセンサーの値を絶えず更新していくような場合に、キューのレシーブ側を考えずに済みます。
xQueueOverwrite(queue1, &count);
出力結果:
10
20
30
40
xQueueOverwriteを使用したときは、出力結果に示す通り、count値の最新値がキューに書かれていることが分かります。
最後に加速度センサMPU6050から加速度、角速度、温度を表示する例を示します。要点としては、キューで扱うデータをstruct Data_t型にしていることです。また、センサーを読むタスク、値を表示するタスクをそれぞれ分けているため、例えば値を表示するタスクをモーター制御を行うタスクに置き換えることも容易に行うことができます
#include <Arduino.h>
#include <Wire.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
void taskSensing(void *pvParameters);
void taskShowData(void *pvParameters);
QueueHandle_t xQueue;
#define MPU6050_ADDR 0x68
#define MPU6050_AX_ADDR 0x3B
#define MPU6050_READ_NUM 14
typedef struct
{
float ax; float ay; float az;
float gx; float gy; float gz;
float tp;
} Data_t;
TaskHandle_t periodicHandle = NULL;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
xQueue = xQueueCreate(5, sizeof(Data_t));
xTaskCreate(taskSensing, "taskSensing", 512, NULL, 1, NULL);
xTaskCreate(taskShowData, "taskShowData", 512, NULL, 1, NULL);
}
void loop() {
// put your main code here, to run repeatedly:
delay(1);
}
void taskSensing(void *pvParameters){
Wire.begin();
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
while(1){
Data_t data;
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(MPU6050_AX_ADDR);
Wire.endTransmission(false);
Wire.requestFrom(MPU6050_ADDR, MPU6050_READ_NUM, true);
int16_t ax=Wire.read()<<8 | Wire.read();
int16_t ay=Wire.read()<<8 | Wire.read();
int16_t az=Wire.read()<<8 | Wire.read();
int16_t tp=Wire.read()<<8 | Wire.read();
int16_t gx=Wire.read()<<8 | Wire.read();
int16_t gy=Wire.read()<<8 | Wire.read();
int16_t gz=Wire.read()<<8 | Wire.read();
data.tp = ((float)tp + 12412.0) / 340.0;
data.ax = ax / 16384.0;
data.ay = ay / 16384.0;
data.az = az / 16384.0;
data.gx = gx / 131.0;
data.gy = gy / 131.0;
data.gz = gz / 131.0;
if(xQueueSend(xQueue, &data, 0) != pdPASS){
Serial.println("no queue space.");
}
delay(100);
}
}
void taskShowData(void *pvParameters){
while(1){
Data_t data;
if(xQueueReceive(xQueue, &data, 0) == pdPASS){
Serial.print(" ax= "); Serial.print(data.ax);
Serial.print(" ay= "); Serial.print(data.ay);
Serial.print(" az= "); Serial.print(data.az);
Serial.print(" gx= "); Serial.print(data.gx);
Serial.print(" gy= "); Serial.print(data.gy);
Serial.print(" gz= "); Serial.print(data.gz);
Serial.print(" temp= "); Serial.print(data.tp);
Serial.println();
}
else {
// no queue
}
delay(10);
}
}
出力結果:
ax= 0.04 ay= 0.01 az= 1.00 gx= -0.69 gy= 1.23 gz= 0.01 temp= 27.38
ax= 0.04 ay= 0.01 az= 1.01 gx= -0.69 gy= 1.31 gz= -0.06 temp= 27.52
ax= 0.04 ay= 0.01 az= 1.01 gx= -0.73 gy= 1.21 gz= 0.02 temp= 27.42
ax= 0.04 ay= 0.01 az= 1.01 gx= -0.76 gy= 1.31 gz= -0.02 temp= 27.42
ax= 0.04 ay= 0.01 az= 1.00 gx= -0.79 gy= 1.29 gz= -0.09 temp= 27.52