您當前的位置 :實況網-重新發現生活>資訊頻道 > 要聞 > 正文
基于STM32的無人售貨機系統設計-世界聚看點
2023-05-17 17:30:04 來源:DS小龍哥-嵌入式技術

一、項目背景

隨著科技的發展和生活水平的提高,人們對于購物體驗的要求越來越高。傳統的商場、超市購物方式已經無法滿足消費者的需求,因此無人售貨機應運而生。本文針對現有售貨機存在的缺陷,設計了一款基于STM32的無人售貨機系統。該系統采用STM32作為主控芯片,使用液晶屏顯示各種商品庫存與售價,用戶按下對應按鍵選擇購買指定商品,在矩陣鍵盤輸入賬號密碼付款。若付款成功,對應電機旋轉一定角度使商品出庫,同時修改庫存;若余額不足,則進行聲光提示。手機端還可查看消費流水、商品庫存情況,并進行補貨和充值操作。

二、系統設計

2.1 系統硬件設計

該系統的核心部件是STM32主控芯片,它負責整個售貨機的控制和管理。液晶屏用于顯示商品信息、價格等,矩陣鍵盤用于用戶輸入賬號密碼進行支付。電機控制板用于控制商品出庫。


(資料圖)

硬件組成:

主控芯片選:STM32F103ZET6 液晶屏選擇:2.8寸TFT-LCD屏 WIFI選擇:ESP8266-WIFI 與手機APP之間通信。模式配置為STA模塊。連接服務器。 電機旋轉角度:28BYJ48步進電機。 控制出貨機出貨物。 矩陣鍵盤:4X4的矩陣鍵盤。

2.2 系統軟件設計

軟件部分主要包括STM32程序和手機APP程序。STM32程序是售貨機的核心程序,負責控制各個部件的工作,實現售貨機的基本功能。APP程序可以通過與STM32通信來實現商品庫存查看、補貨、充值等功能。

STM32部分主要分為以下幾個模塊:

(1)初始化模塊:初始化各個部件的工作狀態和參數。 (2)商品選擇模塊:根據用戶按下的按鈕,選擇相應的商品。 (3)支付模塊:通過矩陣鍵盤輸入賬號密碼進行支付,并根據支付結果控制電機的工作狀態。 (4)庫存管理模塊:根據商品銷售情況,實時更新商品庫存信息。 (5)聲光提示模塊:在用戶付款失敗或余額不足時,通過蜂鳴器和LED燈進行聲光提示。

手機APP程序主要分為以下幾個模塊:

(1)用戶登錄模塊:用戶可以通過輸入賬號密碼登錄APP。 (2)商品查看模塊:用戶可以查看售貨機內商品庫存情況。 (3)補貨模塊:商家可以通過APP進行補貨操作,將商品補充至指定數量。 (4)充值模塊:用戶可以通過APP進行賬戶充值操作。 (5)消費流水模塊:用戶和商家可以查看售貨機的消費記錄。

以上各模塊之間通過STM32和APP程序之間進行通信,實現整個系統的功能。

三、核心代碼實現

【1】步進電機控制代碼

以下是28BYJ48步進電機的代碼:

(1)定義一些宏和變量以便于控制步進電機:

#define IN1 GPIO_Pin_0#define IN2 GPIO_Pin_1#define IN3 GPIO_Pin_2#define IN4 GPIO_Pin_3?#define STEPS_PER_REVOLUTION 2048 //步數每圈#define DELAY_MS 5 //控制轉速的延遲時間?GPIO_InitTypeDef GPIO_InitStructure;?int step_count = 0;uint16_t steps[] = {IN1 | IN2 | IN3 | IN4,          IN2 | IN3 | IN4,          IN1 | IN2 | IN3,          IN3 | IN4,          IN1 | IN3 | IN4,          IN2 | IN4,          IN1 | IN2,          IN4};?void delay_ms(uint32_t ms) {  uint32_t i, j;  for (i = 0; i < ms; i++) {    for (j = 0; j < 1141; j++);   }}?void setStep(int step) {  GPIO_ResetBits(GPIOB, IN1 | IN2 | IN3 | IN4);  GPIO_SetBits(GPIOB, steps[step]);}?void forward(int steps_to_move) {  int i;  for (i = 0; i < steps_to_move; i++) {    setStep(step_count % 8);    step_count++;    delay_ms(DELAY_MS);   }}?void backward(int steps_to_move) {  int i;  for (i = 0; i < steps_to_move; i++) {    setStep(step_count % 8);    step_count--;    delay_ms(DELAY_MS);   }}

在上面的代碼中,定義了四個引腳來控制步進電機,然后定義了一些函數來實現正反轉控制。

delay_ms函數用于延遲控制步進電機的轉速。STEPS_PER_REVOLUTION宏定義了每圈的步數,DELAY_MS宏定義了控制轉速的延遲時間。

setStep函數根據傳入的步數設置引腳狀態,接著forward和backward函數分別根據需要移動的步數控制步進電機的轉動方向,并調用setStep函數控制步進電機的步數。

最后,將forward和backward函數封裝成一個子函數來更方便地調用:

void control_stepper_motor(int steps_to_move, int direction) {  if (direction == 1) {    forward(steps_to_move);   } else {    backward(steps_to_move);   }}

這樣,就可以通過調用control_stepper_motor函數來實現正反轉控制28BYJ48步進電機了。

【2】矩陣鍵盤檢測代碼

以下是4x4電容矩陣鍵盤的示例代碼:

(1)定義一些宏和變量以便于控制電容矩陣鍵盤:

#define ROW1 GPIO_Pin_0#define ROW2 GPIO_Pin_1#define ROW3 GPIO_Pin_2#define ROW4 GPIO_Pin_3?#define COL1 GPIO_Pin_4#define COL2 GPIO_Pin_5#define COL3 GPIO_Pin_6#define COL4 GPIO_Pin_7?GPIO_InitTypeDef GPIO_InitStructure;?const uint8_t keys[4][4] = {   {"1", "2", "3", "A"},   {"4", "5", "6", "B"},   {"7", "8", "9", "C"},   {"*", "0", "#", "D"}};

在上面的代碼中,定義了8個引腳來控制電容矩陣鍵盤,并使用一個二維數組來存儲每個按鍵對應的字符。

(2)需要編寫一個函數來檢測電容矩陣鍵盤是否有按下。

該函數需要通過輪詢掃描鍵盤來檢測按鍵,如果有按鍵按下,則返回該按鍵對應的字符:

char scan_keypad() {  GPIO_ResetBits(GPIOC, ROW1 | ROW2 | ROW3 | ROW4);  GPIO_SetBits(GPIOC, COL1 | COL2 | COL3 | COL4);?  if (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0);    return keys[0][0];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0);    return keys[1][0];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0);    return keys[2][0];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0);    return keys[3][0];   }?  GPIO_ResetBits(GPIOC, ROW1 | ROW2 | ROW3 | ROW4);  GPIO_SetBits(GPIOC, COL1 | COL2 | COL3 | COL4);?  if (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0);    return keys[0][1];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0);    return keys[1][1];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0);    return keys[2][1];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0);    return keys[3][1];   }?  GPIO_ResetBits(GPIOC, ROW1 | ROW2 | ROW3 | ROW4);  GPIO_SetBits(GPIOC, COL1 | COL2 | COL3 | COL4);?  if (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0);    return keys[0][2];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0);    return keys[1][2];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0);    return keys[2][2];   } else if (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0) {    while (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0);      return keys[3][2];}GPIO_ResetBits(GPIOC, ROW1 | ROW2 | ROW3 | ROW4);GPIO_SetBits(GPIOC, COL1 | COL2 | COL3 | COL4);?if (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0) {  while (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0);  return keys[0][3];} else if (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0) {  while (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0);  return keys[1][3];} else if (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0) {  while (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0);  return keys[2][3];} else if (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0) {  while (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0);  return keys[3][3];}?return "?"; }

在上面的代碼中,使用輪詢的方式掃描鍵盤。首先將所有行引腳都設為低電平,所有列引腳都設為高電平,并檢測是否有按鍵按下。如果有按鍵按下,則返回該按鍵對應的字符。 接下來,可以在主函數中循環調用scan_keypad函數來讀取鍵值:

int main(void) {  char key = "?";?  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);?  GPIO_InitStructure.GPIO_Pin = ROW1 | ROW2 | ROW3 | ROW4;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_Init(GPIOC, &GPIO_InitStructure);?  GPIO_InitStructure.GPIO_Pin = COL1 | COL2 | COL3 | COL4;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_Init(GPIOC, &GPIO_InitStructure);?  while (1) {    key = scan_keypad();?    if (key != "?") {      // 處理讀取到的鍵值     }   }}

在上面的代碼中,首先初始化了8個引腳,并通過循環調用scan_keypad函數來讀取鍵值。如果讀取到鍵值,則可以進行相應的處理。

四、系統測試與驗證

為了驗證系統的可行性和穩定性,在硬件搭建完成后,進行了一系列測試。

(1)測試了系統的整體運行邏輯。通過模擬用戶選擇商品、支付、出貨等情況,驗證系統的基本功能。測試結果顯示系統能夠穩定運行,能夠滿足用戶的購物需求。

(2)測試了系統的庫存管理功能。通過模擬商品銷售情況,驗證系統的庫存信息是否能夠實時更新。測試結果表明系統能夠準確地處理庫存信息。

(3)測試了手機端APP程序的功能。通過模擬用戶登錄、查看商品庫存、進行補貨、充值和查看消費流水等操作,驗證APP程序的功能。測試結果顯示APP程序能夠正常運行,并且與STM32主控芯片之間能夠實現良好的通信。審核編輯:湯梓紅

關鍵詞:

相關閱讀
分享到:
版權和免責申明

凡注有"實況網-重新發現生活"或電頭為"實況網-重新發現生活"的稿件,均為實況網-重新發現生活獨家版權所有,未經許可不得轉載或鏡像;授權轉載必須注明來源為"實況網-重新發現生活",并保留"實況網-重新發現生活"的電頭。

国产又粗又猛又黄视频,97超碰亚洲中文字幕校园,中文字幕在线视频网站,国产阿v视频高清在线观看
亚洲人成影院在线播放高清 | 日本一区二区人妖 | 在线视频免费国产午夜 | 最新国产国语对白 | 夜夜爽天天爽一区 | 亚洲国产精品视频中文字幕 |