/*
程序: Event Group - Wait Bits
公众号:孤独的二进制
注意: 模拟器这里可能有个问题,按钮一次按钮后,
有50%的几率一直保持LOW状态
导致重复不断的购买
没道理呀,大家可以一起来找Bug
API:
xEventGroupCreate
xEventGroupSetBits
xEventGroupWaitBits
xEventGroupGetBits
xEventGroupClearBits
*/
#define BTNPIN 23 //按钮
#define ADDTOCART_0 ( 1 << 0 ) //0001 bit0
#define PAYMENT_1 ( 1 << 1 ) //0010 bit1
#define INVENTORY_2 ( 1 << 2 ) //0100 bit2
#define ALLBITS 0xFFFFFF //24bits都是1
EventGroupHandle_t xEventPurchase = NULL; //创建event handler
const TickType_t xTimeOut = 10000 / portTICK_PERIOD_MS; // 10秒
//const TickType_t xTimeOut = portMAX_DELAY; //无限等待
void addtocartTask(void *pvParam) {
pinMode(BTNPIN, INPUT);
while (1) {
if (digitalRead(BTNPIN) == LOW) {
Serial.println("用户真心决定下单了...");
//放一些随机的延迟,否则运行的太快了,看不出效果
for (int i = 0; i < random(100, 200); i++) vTaskDelay(10);
xTaskCreate(purchaseTask, "Purchase", 1024 * 6, NULL, 1, NULL);
xTaskCreate(paymentTask, "Payment", 1024 * 6, NULL, 1, NULL);
xTaskCreate(inventoryTask, "Inventory", 1024 * 6, NULL, 1, NULL);
vTaskDelay(120); //按钮防止抖动
}
}
}
void purchaseTask(void *pvParam) {
EventBits_t uxBits; // Event Group 24Bits 的 值
while (1) {
uxBits = xEventGroupSetBits(xEventPurchase, ADDTOCART_0); // 将bit 0 设置为1
if ((uxBits & ADDTOCART_0)) {
Serial.println("商品已经添加到了购物车,付款中...");
Serial.print(" Event Group Value:");
Serial.println(uxBits, BIN);
}
uxBits = xEventGroupWaitBits (xEventPurchase, //Event Group Handler
ADDTOCART_0 | PAYMENT_1 | INVENTORY_2, //等待Event Group中的那个Bit(s)
pdFALSE, //执行后,对应的Bits是否重置为 0
pdTRUE, //等待的Bits判断关系 True为 AND, False为 OR
xTimeOut);
if ((uxBits & ADDTOCART_0) && (uxBits & PAYMENT_1) && (uxBits & INVENTORY_2)) {
//随机延迟, 模拟网页显示,恭喜买家入手商品
for (int i = 0; i < random(100, 200); i++) vTaskDelay(10);
xEventGroupClearBits(xEventPurchase, ALLBITS); //重置
uxBits = xEventGroupGetBits(xEventPurchase); //读取
Serial.println("交易完成, RESET Event Group");
Serial.print(" Event Group Value:");
Serial.println(uxBits, BIN);
Serial.println("");
}
vTaskDelete(NULL);
//vTaskDelay(10000);
}
}
void paymentTask(void *pvParam) {
while (1) {
EventBits_t uxBits;
uxBits = xEventGroupWaitBits (xEventPurchase, //Event Group Handler
ADDTOCART_0, //等待Event Group中的那个Bit(s)
pdFALSE, //执行后,对应的Bits是否重置为 0
pdTRUE, //等待的Bits判断关系 True为 AND, False为 OR
xTimeOut);
// 代表ADDTOCART_0被设置为了 1
if (uxBits & ADDTOCART_0) {
//随机延迟, 模拟付款验证过程
for (int i = 0; i < random(100, 200); i++) vTaskDelay(10);
uxBits = xEventGroupSetBits(xEventPurchase, PAYMENT_1); // 将bit1 PAYMENT_1 设置为1
Serial.println("支付宝付款完成,可以出货...");
Serial.print(" Event Group Value:");
Serial.println(uxBits, BIN);
vTaskDelete(NULL);
}
}
}
void inventoryTask(void *pvParam) {
EventBits_t uxBits;
while (1) {
uxBits = xEventGroupWaitBits (xEventPurchase, //Event Group Handler
ADDTOCART_0 | PAYMENT_1, //等待Event Group中的那个Bit(s)
pdFALSE, //执行后,对应的Bits是否重置为 0
pdTRUE, //等待的Bits判断关系 True为 AND, False为 OR
xTimeOut);
// 判断 Event Group 中 ADDTOCART_0 和 PAYMENT_1 是否被设置为了0
if ((uxBits & ADDTOCART_0) && (uxBits & PAYMENT_1)) {
//随机延迟, 模拟仓库出货过程
for (int i = 0; i < random(100, 200); i++) vTaskDelay(10);
uxBits = xEventGroupSetBits(xEventPurchase, INVENTORY_2); // 将bit2 INVENTORY_2 设置为1
Serial.println("仓库出货完成,快递已取货...");
Serial.print(" Event Group Value:");
Serial.println(uxBits, BIN);
vTaskDelete(NULL);
}
}
}
void setup()
{
Serial.begin(115200);
xEventPurchase = xEventGroupCreate(); //创建 event group
xTaskCreate(addtocartTask, "Add To Cart", 1024 * 4, NULL, 1, NULL);
}
void loop() {}