|
|
深入学习arduino基本上是从极客工坊这个论坛开始的,看了精华区的很多教程,非常感谢有这个论坛,也非常感谢那些愿意跟大家分享学习心得的朋友。
为了回馈论坛,特地奉献上本人最近利用arduino uno开发的一个商业项目源代码,PCB以及其它器件资料因为商业因素,不便透露,敬请谅解。
本项目用了18B20进行温度测量,用到PID对温度进行恒温控制,用到定时器TIMER1进行了步进电机的速度控制,另外对串口、EEPROM的读写操作也比较多,有兴趣的朋友可以作为参考。
本人之前从事过一些C51项目的开发,对arduino其实不算精通,因此基本上是拿来主义,不求甚解,因此很多细节的问题我无法做深入的解答,但设计思路方面,可以与我讨论(其实最重要是解决问题的思路)。
- #include <EEPROM.h>
- unsigned char recordMaxID = 0; //组号
- unsigned int targetTemp = 0; //设定温度
- unsigned char targetSpeed = 0; //设定速度
- //========================================================================================================================================
- #include <TimerOne.h>
- #define PIN_ENCODER 2 //光电位移计数开关(外部中断源0)
- #define PIN_LIMIT 3 //极限位置开关(外部中断源1)
- #define PIN_ZERO 4 //零位开关
- #define PIN_PULSE 5 //脉冲
- #define PIN_DIR 6 //方向
- boolean pulseLevel = LOW; //脉冲
- boolean pulseDir = HIGH; //方向(LOW-正转,HIGH-反转)
- unsigned int Distence = 0; //位移计数值
- boolean FlagRun = false; //运行状态
- //========================================================================================================================================
- #include <OneWire.h>
- #include <DallasTemperature.h>
- #define TEMPERATURE_PRECISION 12 //温度采集精度12位
- #define PIN_TEMP 8 //温度传感器
- DeviceAddress tempDeviceAddress1;
- OneWire oneWire1(PIN_TEMP);
- DallasTemperature sensors1(&oneWire1);
- double CurrentTemp = 0;
- //========================================================================================================================================
- #include <PID_v1.h>
- #define PIN_BUMP 11 //水泵
- #define PIN_HOT 12 //加热管继电器
- #define PIN_COOL 13 //压缩机继电器
- double Ki = 0,Kp = 0,Kd = 0;
- double Setpoint, Input, Output; //目标温度值,输入值,输出值
- PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
- int WindowSize = 5000; //温度控制周期5s
- unsigned long windowStartTime = 0;
- boolean FlagTempCtrl = false;
- boolean BumpState = HIGH;
- //========================================================================================================================================
- unsigned char SampleID = 0;
- unsigned int Ductility[3];
- unsigned char readRecordID = 1;
- //========================================================================================================================================
- void initGPIO()
- {
- pinMode(PIN_ENCODER,INPUT);
- pinMode(PIN_LIMIT,INPUT);
- pinMode(PIN_ZERO,INPUT);
- pinMode(PIN_BUMP,OUTPUT);
- pinMode(PIN_HOT,OUTPUT);
- pinMode(PIN_COOL,OUTPUT);
- pinMode(PIN_PULSE,OUTPUT);
- pinMode(PIN_DIR,OUTPUT);
- digitalWrite(PIN_BUMP,HIGH);
- digitalWrite(PIN_HOT,HIGH);
- digitalWrite(PIN_COOL,HIGH);
- digitalWrite(PIN_PULSE,LOW);
- digitalWrite(PIN_DIR,LOW);
- }
- //========================================================================================================================================
- void init18B20()
- {
- sensors1.begin();
- sensors1.getAddress(tempDeviceAddress1,0);
- sensors1.setResolution(tempDeviceAddress1,TEMPERATURE_PRECISION);
- }
- void initPID()
- {
- Setpoint = float(targetTemp / 10.0);
- myPID.SetTunings(Kp,Ki,Kd);
- myPID.SetOutputLimits(0, WindowSize);
- myPID.SetControllerDirection(DIRECT);
- myPID.SetMode(AUTOMATIC);
- }
- void tempCtrlStart()
- {
- //1.打开压缩机
- initPID();
- digitalWrite(PIN_COOL,LOW);
- //2.采集温度,温控输出
- sensors1.requestTemperatures();
- CurrentTemp = sensors1.getTempC(tempDeviceAddress1);
- unsigned int Temp=CurrentTemp*100;
- unsigned char tempChar[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x0F, char(Temp>>8), char(Temp & 0x00FF) };
- Serial.write(tempChar,8);
- //3.温度控制
- Input = CurrentTemp;
- myPID.Compute();
- unsigned long now = millis();
- if(now - windowStartTime > WindowSize)
- windowStartTime += WindowSize;
- if(Output < now - windowStartTime)
- digitalWrite(PIN_HOT,HIGH);//OFF
- else
- digitalWrite(PIN_HOT,LOW);//ON
- }
- void tempCtrlStop()
- {
- FlagTempCtrl = false;
- digitalWrite(PIN_COOL,HIGH);
- digitalWrite(PIN_HOT,HIGH);
- }
- //========================================================================================================================================
- unsigned long getTime;
- void getDistance()
- {
- if(pulseDir == LOW)
- {
- if(digitalRead(PIN_LIMIT) == LOW)
- {
- Timer1.stop();
- }
- }
- if(pulseDir == HIGH)
- {
- if(digitalRead(PIN_ZERO) == LOW)
- {
- Timer1.stop();
- }
- }
- if(FlagRun == true)
- {
- if(digitalRead(PIN_ENCODER) == LOW)
- {
- unsigned int delayTime = 0;
- if(targetSpeed == 50)
- {
- delayTime = 480;
- }
- else
- {
- delayTime = 2400;
- }
- if((millis() - getTime) > delayTime)
- {
- getTime = millis();
- Distence++;
- unsigned char setChar[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x09+SampleID,Distence>>8,Distence & 0x00FF };
- Serial.write(setChar,8);
- }
- }
- }
- }
- void pulse()
- {
- getDistance();
- pulseLevel =! pulseLevel;
- digitalWrite(PIN_PULSE,pulseLevel);
- }
- void initTimer1()
- {
- Timer1.initialize(58);
- Timer1.attachInterrupt(pulse);
- Timer1.stop();
- }
- void moveMotor(unsigned int mySpeed ,boolean myDir)
- {
- digitalWrite(PIN_DIR,myDir);
- pulseDir = myDir;
- switch(mySpeed)
- {
- case 10:
- Timer1.setPeriod(2344);
- break;
- case 50:
- Timer1.setPeriod(469);
- break;
- case 400:
- Timer1.setPeriod(58);
- break;
- default:
- Timer1.setPeriod(58);
- break;
- }
- Timer1.restart();
- }
- //========================================================================================================================================
- void readSetting()
- {
- recordMaxID = EEPROM.read(0);
- if(recordMaxID > 100)
- {
- recordMaxID = 1;
- EEPROM.write(0,recordMaxID);
- }
- targetTemp = (EEPROM.read(1)<<8)+EEPROM.read(2);
- targetSpeed = EEPROM.read(3);
- unsigned int iKp,iKi,iKd;
- iKp = (EEPROM.read(4)<<8)+EEPROM.read(5);
- iKi = (EEPROM.read(6)<<8)+EEPROM.read(7);
- iKd = (EEPROM.read(8)<<8)+EEPROM.read(9);
- Ki = float(iKi);
- Kd = float(iKd);
- Kp = float(iKp);
- unsigned char Para[22] = {
- 0x5A,0xA5,0x13,0x82,0x00,0x70,0x00,recordMaxID,targetTemp>>8,targetTemp & 0x00FF,0x00,targetSpeed,iKp>>8,iKp & 0x00FF,iKi>>8,iKi & 0x00FF,iKd>>8,iKd & 0x00FF,0x00,targetSpeed,targetTemp>>8,targetTemp & 0x00FF };
- Serial.write(Para,22);
- }
- void saveSetting()
- {
- String indata = "";
- unsigned char getPara[7] = {
- 0x5A,0xA5,0x04,0x83,0x00,0x71,0x05 };
- Serial.write(getPara,7);
- delay(200);
- while (Serial.available() > 0)
- {
- indata += char(Serial.read());
- delay(2);
- }
- if(indata.length() > 0)
- {
- EEPROM.write(1,indata[7]);
- EEPROM.write(2,indata[8]);
- //targetTemp = (indata[7]<<8)+indata[8];写法有错但没找到原因,所以用下一句实现
- targetTemp = (EEPROM.read(1)<<8)+EEPROM.read(2);
- EEPROM.write(3,indata[10]);
- targetSpeed = indata[10];
- EEPROM.write(4,indata[11]);
- EEPROM.write(5,indata[12]);
- Kp = float((indata[11]<<8)+indata[12]);
- EEPROM.write(6,indata[13]);
- EEPROM.write(7,indata[14]);
- Ki = float((indata[13]<<8)+indata[14]);
- EEPROM.write(8,indata[15]);
- EEPROM.write(9,indata[16]);
- Kd = float((indata[15]<<8)+indata[16]);
- unsigned char setPara[10] = {
- 0x5A,0xA5,0x07,0x82,0x00,0x76,0x00,indata[10],indata[7],indata[8] };
- Serial.write(setPara,10);
- }
- indata = "";
- }
- void saveRecord()
- {
- Ductility[SampleID] = Distence;
- SampleID++;
-
- if(SampleID == 3)
- {
- Timer1.stop();
- FlagRun = false;
- unsigned char TestOFF[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x12,0x00,0x00
- };
- Serial.write(TestOFF, 8);
- delay(50);
-
- SampleID = 0;
- unsigned int AVG = 0;
- AVG = int((Ductility[0]+Ductility[1]+Ductility[2])/3);
- unsigned char setPara[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x0C,AVG>>8,AVG & 0x00FF };
- Serial.write(setPara,8);
- EEPROM.write(0,recordMaxID);
- EEPROM.write(20+recordMaxID*6 + 1,Ductility[0]>>8);
- EEPROM.write(20+recordMaxID*6 + 2,Ductility[0] & 0x00FF);
- EEPROM.write(20+recordMaxID*6 + 3,Ductility[1]>>8);
- EEPROM.write(20+recordMaxID*6 + 4,Ductility[1] & 0x00FF);
- EEPROM.write(20+recordMaxID*6 + 5,Ductility[2]>>8);
- EEPROM.write(20+recordMaxID*6 + 6,Ductility[2] & 0x00FF);
- if(recordMaxID < 100)
- recordMaxID++;
- else
- recordMaxID = 1;
- }
- }
- void readRecord(unsigned char id)
- {
- delay(50);
- unsigned int s1,s2,s3,avg;
- s1=(EEPROM.read(20+id*6 + 1)<<8)+EEPROM.read(20+id*6 + 2);
- s2=(EEPROM.read(20+id*6 + 3)<<8)+EEPROM.read(20+id*6 + 4);
- s3=(EEPROM.read(20+id*6 + 5)<<8)+EEPROM.read(20+id*6 + 6);
- avg=(s1+s2+s3)/3;
-
- unsigned char setRecord[16] = {
- 0x5A,0xA5,0x0D,0x82,0x00,0x13,0x00,id,s1>>8,s1 & 0x00ff,s2>>8,s2 & 0x00ff,s3>>8,s3 & 0x00ff,avg>>8,avg & 0x00ff
- };
- Serial.write(setRecord,16);
- }
- //========================================================================================================================================
- void readComm()
- {
- unsigned char TestOFF[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x12,0x00,0x00 };
- unsigned char TestON[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x12,0x00,0x01 };
-
- unsigned char TempON[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x0E,0x00,0x01 };
- unsigned char TempOFF[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x0E,0x00,0x00 };
- unsigned char BumpON[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x0D,0x00,0x01 };
- unsigned char BumpOFF[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x0D,0x00,0x00 };
- unsigned char setChar[14] = {
- 0x5A,0xA5,0x0b,0x82,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
- unsigned char setmaxRecordID[8] = {
- 0x5A,0xA5,0x05,0x82,0x00,0x70,0x00,recordMaxID };
-
- String indata = "";
- while (Serial.available() > 0)
- {
- indata += char(Serial.read());
- delay(2);
- }
- if(indata.length() > 0)
- {
- switch (indata[8])
- {
- case 0x01://归零
- if(FlagRun == false)
- moveMotor(400,HIGH);
- break;
- case 0x02://记录
- if(FlagRun == true)
- saveRecord();
- break;
- case 0x03://前进
- if(FlagRun == false)
- moveMotor(targetSpeed,LOW);
- break;
- case 0x04://后退
- if(FlagRun == false)
- moveMotor(targetSpeed,HIGH);
- break;
- case 0x05://开始
- if(FlagRun == false)
- {
- FlagRun = true;
- Serial.write(TestON, 8);
- delay(50);
-
- SampleID = 0;
- Distence = 0;
- Ductility[0] = 0;
- Ductility[1] = 0;
- Ductility[2] = 0;
- Serial.write(setChar,14);
- delay(50);
- Serial.write(setmaxRecordID,8);
-
- moveMotor(targetSpeed,LOW);
- }
- break;
- case 0x06://水泵
- BumpState = !BumpState;
- digitalWrite(PIN_BUMP,BumpState);
- if(BumpState == false)
- {
- Serial.write(BumpON,8);
- }
- else
- {
- Serial.write(BumpOFF,8);
- }
- break;
- case 0x07://温控
- FlagTempCtrl = !FlagTempCtrl;
- if(FlagTempCtrl == false)
- {
- tempCtrlStop();
- Serial.write(TempOFF, 8);
- }
- else
- {
- Serial.write(TempON, 8);
- }
- break;
- case 0x08: //停止
- Timer1.stop();
- FlagRun = false;
- Serial.write(TestOFF, 8);
- break;
- case 0x11: //参数保存
- saveSetting();
- break;
- case 0x18://查询前翻页
- readRecordID--;
- if(readRecordID==0)
- {
- readRecordID = 100;
- }
- readRecord(readRecordID);
- break;
- case 0x19://查询后翻页
- readRecordID++;
- if(readRecordID==101)
- {
- readRecordID = 1;
- }
- readRecord(readRecordID);
- break;
- }
- }
- indata = "";
- }
- //========================================================================================================================================
- void setup()
- {
- unsigned char LED[7] = {
- 0x5A,0xA5,0x03,0x80,0x01,0x40 };
- unsigned char PIC[8] = {
- 0x5A,0xA5,0x04,0x80,0x03,0x00,0x01 };
-
- Serial.begin(9600);
- delay(2500);
- Serial.write(LED, 7);
- delay(50);
- Serial.write(PIC, 8);
- delay(50);
- readSetting();
- initGPIO();
- init18B20();
- windowStartTime = millis();
- initTimer1();
- //moveMotor(400,HIGH);
- }
- void loop()
- {
- readComm();
- if(FlagTempCtrl == true)
- tempCtrlStart();
- }
复制代码
|
|