图6 STM32F429的工程的user文件夹包含自编的外设和库
以下为部分Arduino Mega2560的源程序(颜色传感器采用TCS3200版本)
/*
* stm32:串口读取-》计数-》显示各部分状态及钱币金额,开启关闭整个机器的功能
* Arduino:红外检测-》关闭红外,关闭步进电机-》颜色检测-》串口发送-》开启电机-》红外检测
* Arduino每一部均通过串口向stm32发送状态,格式:
* 作为主机每条命令发送一个字节(最后一位为0代表各阶段开始,1代表完成,【】内为机器状态,由stm32触摸屏显示)
* 0010 0010:机器初始化 0010 0011:机器初始化完成,红外检测中,未有钱币通过【红外中断开启,步进电机1开启,直流电机1、2、3、4开启,直流电机5、6关闭,步进电机2待定】
* 0010 0100:发现钱币,颜色检测中【红外中断关闭,步进电机1关闭,颜色传感器I2C读取,直流电机1、2、3、4开启,直流电机5、6关闭,步进电机2待定】
* 0010 1000:串口开始发送颜色数据,机器状态不变,接下来发送8字节(RGBW各两字节)
* 发送完成后stm32显示分拣状态【显示正在入库的金额,红外中断关闭,步进电机1开启,直流电机1、2、3、4关闭,直流电机5、6其中有一个开启、一个关闭,步进电机2待定】
* 等待stm32发送命令(1100xxxx,最高位为1,第4至6位为中间三位为命令,100代表检测成功开始入库,第3位为控制左右电机(直流电机5、6,1为电机5,0为电机6),0至2位为控制步进电机走的距离,共可以有8*2=16个分区)
* 完成该步后循环整个过程,发送00000001:机器继续运行【红外中断开启,步进电机1开启,直流电机1、2、3、4开启,直流电机5、6关闭,步进电机2待定】
*
*/
#include
#include
#include
#define LED 9
u8 readByte=0;
bool flag1=0;//标志位1,在中断处理函数中若Arduino接收到STM32串口传来的数据则清0,以执行STM32发送的命令
void MachineInit()
{
Serial.print(0x22);//34,Machine init......
//LED初始化
pinMode(LED,OUTPUT);
//打开LED
digitalWrite(LED,LOW);
//步进电机初始化
StepperInit(PStepper1,PStepper2);
//直流电机初始化
DCmotorInit();
//颜色传感器初始化
TSC_Init();
//直流电机开启
DCmotorON();
//步进电机关闭
StepperOFF(PStepper1);
StepperOFF(PStepper2);
//机器初始化完成
Serial.print(0x23);//35,Machine init succeed!!!
}
//中断处理函数
void BillTrigger()
{
Serial.print(0x24);//36,Paper money recognition...... //颜色检测开始
//关闭电机,开始检测
DCmotorOFF();
//串口开始发送RGBW数据
Serial.print(0x28);//Prepare to receive RGBW values......
/*********************Serial.print(RGB数据)***************************************/
TSC_ReadPulseSend(); //VEML6040的I2C读取程序单独写在了该篇经验上方
/*********************Serial.print(RGB数据)***************************************/
//此处已向STM32发送完RGBW数据,退出中断函数在主程序中等待STM32的命令
//串口接收标志位,只有当STM32处理完颜色数据并通过串口通讯告诉Arduino该如何控制电机,
//flag1才会清0,程序才会继续,即回到传输电机转动的情况
flag1 = 1;
}
void setup()
{
//串口初始化
Serial.begin(115200);
//等待1s,让stm32初始化完成
delay(1000);
//中断函数(红外检测)初始化
attachInterrupt(0,BillTrigger,FALLING);//下降沿触发中断,进入颜色识别程序
//机器初始化
MachineInit();
}
void loop()
{
while(flag1==1)//arduino等待接收stm32命令的状态
{
/**************************stm32处理数据中****************************/
if(Serial.available()>0) //stm32处理完成,开始接收命令并执行入库
{
readByte=Serial.read();
flag1=0;
switch(readByte)
{
case 201://0xc9,0.1元
{
StepperTransport(value_0_1);
}break;
case 193://0xc1,0.5元
{
StepperTransport(value_0_5);
}break;
case 202://0xca,1元
{
StepperTransport(value_1);
}break;
case 194://0xc2,5元
{
StepperTransport(value_5);
}break;
case 203://0xcb,10元
{
StepperTransport(value_10);
}break;
case 195://0xc3,100元
{
StepperTransport(value_100);
}break;
default://未成功识别
StepperTransport(value_unknown);
}//switch结束
//机器进入循环
MachineInit();
}
}//while(flag1==1) END,此时flag1==0
//不处于检测状态时,程序一直为步进电机(传送带)前进
StepperON(PStepper1,forward,1600,mSpeed);
}
以下为自编Arduino库函数MyStepper.h的头文件,采用DM542步进电机驱动器,57步进电机
#ifndef __MYSTEPPER_H
#define __MYSTEPPER_H
/* define data type */
#define u8 unsigned char
#define u16 unsigned int
/* define Stepper1/2 pins */
#define STEPPER1_PULSE 6
#define STEPPER1_DIR 7
#define STEPPER1 8
#define STEPPER2_PULSE 9
#define STEPPER2_DIR 10
#define STEPPER2 11
/* define StepperDir values */
#define forward true
#define backward false
/* set Stepper speed */
extern u8 sSpeed;
extern u8 mSpeed;
extern u8 fSpeed;
/* 存储抽屉当前位置 */
extern u8 nowPos;
/* typedef StepperDef struct */
/***********************************************************************/
typedef struct
{
u8 PulsePin;
u8 DirPin;
u8 ENAPin;
} StepperDef;
extern StepperDef Stepper1;
extern StepperDef Stepper2;
extern StepperDef * PStepper1;
extern StepperDef * PStepper2;
/*Stepper1 = malloc(sizeof(StepperDef)); //分配安全的地址
Stepper2 = malloc(sizeof(StepperDef)); //分配安全的地址*/
/***********************************************************************/
/* define the money value */
/***********************************************************************/
#define value_unknown 0
#define value_0_1 1
#define value_0_5 2
#define value_1 3
#define value_5 4
#define value_10 5
#define value_100 6
/***********************************************************************/
//定义步进电机1(传送带电机)到达收集处所需要运行的圈数
#define ROUND 20
//定义步进电机2(收集装置)上升一层需要的步数
#define StepsForOne 1600
//定义步进电机1(传送带电机)将纸币送入收集装置需要的步数
#define InSteps 3200
/* 函数定义 */
void StepperInit(StepperDef *stepper1,StepperDef *stepper2);
void StepperON(StepperDef *StepperNum,bool StepperDir,u16 Steps,u8 speed);
void StepperOFF(StepperDef *StepperNum);
void StepperPulse(StepperDef *StepperNum,u16 PulseNum,u8 speed);
void StepperTransport(u8 value);
void StepperTest();
#endif /* __MYSTEPPER_H */
以下为STM32F429的main.c文件,大量封装函数使主函数简洁明了
/**
******************************************************************************
* @date 2017-xx-xx
* @brief 钱币智能分拣计数系统
******************************************************************************
**/
#include "./machine/machine.h"
/**
* @brief main函数
* @param 无
* @retval 无
* @interrupt EXTI4_IRQHandler(红外检测硬币数目)
*/
int main(void)
{
/* 机器初始化 */
machineInit();
Delay(0xffff);
Display_Welcome();
Delay(0xffffff);
LCD_Clear(LCD_COLOR_BLACK);
/* 读串口命令 */
while(1)
{
ReadCommand();
Delay(0xffffff);
}
}
/*********************************************END OF FILE**********************/
三,完成图(整体完成度60%,程序大部分已完成)
四,总结
五一和最近几天熬了很多个晚上小有成果,我是学物联网工程的,机械结构由机械和能动学院的大佬学长们完成,我负责控制和软件部分。这两天焊板子、接线到昏厥,看到长得像电焊的东西总感觉到一股焊锡味和热气。。重要的是过程,无论什么时候都还会有很大的提升空间。这个月准备尝试图像识别纸币,颜色检测方面通过机器自主参数调节让纸币识别更准确,还有好的意见和建议欢迎大家提出来~