Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <mcp_can.h>
- #include <SPI.h>
- #include "MPU6050_6Axis_MotionApps20.h"
- #include <EEPROM.h>
- #include <sav_button.h>
- // время показа данных на магнитоле
- #define TIME_MOT 6000UL // 6 секунд отображения температуры ОЖ, можно поставить свои значения
- #define TIME_EXT 6000UL // 6 секунд отображения наружной температуры, можно поставить свои значения
- #define TIME_VOLT 6000UL // 6 секунд отображения напряжения, можно поставить свои значения
- #define TIME_FUEL 6000UL // 6 секунд отображения уровня топлива, можно поставить свои значения
- #define DELAY_DATA 10UL // задержка перед записью новых данных 10 мс
- #define DELAY_DATA2 2000UL //время 2 сек.,через которое в магнитолу записываются старые данные и время обновления показаний, чтоб не было постоянных скачков.
- #define DELAY_MPU 200UL //задержка при отправки данных с гироскопа
- #define TEMP_LIMIT 100UL // температура ОЖ, при которой выводится предупреждение в верхней строке
- MPU6050 mpu;
- uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
- uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
- uint16_t fifoCount; // count of all bytes currently in FIFO
- uint8_t fifoBuffer[64]; // FIFO storage buffer
- // orientation/motion vars
- Quaternion q; // [w, x, y, z] quaternion container
- VectorFloat gravity; // [x, y, z] gravity vector
- float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
- int pitch, roll, pitch2, roll2 =0;
- unsigned long timeMpu, timeData, delayData, delayData2, time2, time3 = 0;
- long unsigned int rxId,rxId2;
- unsigned int data, newData, engTemp, extTemp, batVolt, fuelLev, flag2 = 0x0;
- bool refreshData = false;
- bool refreshData2 = true; //разрешаем обновление данных
- byte flag, flag3;
- int address = 0; // Переменная для хранения адреса
- int address2 = 10; // Переменная для хранения адреса
- int address3 = 20; // Переменная для хранения адреса
- int corroll, corpitch;
- SButton button1(9,50,2000,4000,500); // пин,время антидребезга мс, время длинного нажатия мс, время следующего длиного нажатия, время двойного клика
- unsigned char len, len2 = 0;
- unsigned char rxBuf[8], rxBuf2[8];
- unsigned char stmp[8],info44[8],stmp4[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // шаблон сообщения
- unsigned char stmp2[8] = {0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00}; // шаблон сообщения
- unsigned char stmp3[8] = {0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00}; // шаблон сообщения
- MCP_CAN CAN1(5); // Устанавливаем CS для приёма с 1 шины на пин 5
- MCP_CAN CAN2(10); // Устанавливаем CS для отправки на 2 шину на пин 10
- void setup(){
- while (CAN_OK != CAN1.begin(CAN_500KBPS, MCP_8MHz));
- while (CAN_OK != CAN2.begin(CAN_500KBPS, MCP_8MHz));
- mpu.dmpInitialize();
- // supply your own gyro offsets here, scaled for min sensitivity
- mpu.setXGyroOffset(220);
- mpu.setYGyroOffset(76);
- mpu.setZGyroOffset(-85);
- mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
- mpu.setDMPEnabled(true);
- // get expected DMP packet size for later comparison
- packetSize = mpu.dmpGetFIFOPacketSize();
- EEPROM.get(address, corroll); // считываем из памяти коррекцию roll
- address += sizeof(int);
- EEPROM.get(address, corpitch); // считываем из памяти коррекцию pitch
- address = 0;
- flag3=EEPROM.read(20);
- if(flag3>1){flag3=1;}
- if(flag3==1){flag=1;}
- else{flag=EEPROM.read(10);}
- if(flag>4){flag=1;}
- button1.begin();
- }
- void loop(){
- CAN1.readMsgBuf(&len, rxBuf); // Чтение данных: len = data length, buf = data byte(s)
- rxId = CAN1.getCanId(); //Получаем ID сообщения
- if(rxId == 0x646){CAN2.sendMsgBuf(0x314, 0, 8, rxBuf); stmp4[1]=rxBuf[1]; CAN2.sendMsgBuf(0x548, 0, 8, stmp4);}// Driving ECO2
- if(rxId == 0x699){CAN2.sendMsgBuf(0x31B, 0, 8, rxBuf);}// Отправляем данные климат контроля
- if(rxId == 0x5DA){engTemp=rxBuf[0];}//температура двигателя
- if(rxId == 0x3B7){extTemp=rxBuf[0];}//внешняя температура
- if(rxId == 0x4AC){batVolt=(rxBuf[1]*0.6)+100;}//напряжение АКБ
- if(rxId == 0x6FB){fuelLev=(rxBuf[3]/2.0)+40;}//уровень топлива
- if(rxId == 0x699){flag2=rxBuf[2];}
- // переключение показаний в зависимости от установленных значений времени
- if(flag3==1){
- if(flag==1){
- if(timeData + TIME_MOT <= millis()) {refreshData2 = true; flag = 2; timeData=millis();}
- }
- if(flag==2){
- if(timeData + TIME_EXT <= millis()) {refreshData2 = true; flag = 3; timeData=millis();}
- }
- if(flag==3){
- if(timeData + TIME_VOLT <= millis()) {refreshData2 = true; flag = 4; timeData=millis();}
- }
- if(flag==4){
- if(timeData + TIME_FUEL <= millis()) {refreshData2 = true; flag = 1; timeData=millis();}
- }
- }
- if(flag==1){newData=engTemp;}
- if(flag==2){newData=extTemp;}
- if(flag==3){newData=batVolt;}
- if(flag==4){newData=fuelLev;}
- // Если данные изменились , то перед посылом новых, обнуляем показания, проверяем это раз в 2 секунды, а не постоянно, ибавляемся от скачков
- if (!refreshData &&(refreshData2 || delayData2+DELAY_DATA2 <= millis())){
- if (refreshData2){refreshData2=false;}
- delayData2=millis();
- if(newData != data){
- refreshData=true;//разрешаем запись новых данных
- stmp[2]=0xFF;
- CAN2.sendMsgBuf(0x558, 0, 8, stmp); // сброс
- delayData=millis();
- }
- }
- if(refreshData) { // если разрешено обновить данные
- if(delayData+DELAY_DATA <= millis()) { //то ждём 10 мс, не останавливая общий цикл работы
- refreshData=false;
- data=newData; // пишем новые данные
- stmp[2]=data;
- CAN2.sendMsgBuf(0x558, 0, 8, stmp); //отправляем данные в MediaNav.
- delayData2=millis();
- delayData=millis();
- }
- }else{
- /*записываем старые данные, если не прописались новые, раз в 2 секунды
- т.к.если в течении 4 секунд магнитола не получает хоть какие нибудь данные, получаем прочерки,
- не долбим магнитолу постоянно бесполезными одинаковыми данными
- */
- if(delayData+DELAY_DATA2 <= millis()){CAN2.sendMsgBuf(0x558, 0, 8, stmp);delayData=millis();}
- }
- if((engTemp-40)>TEMP_LIMIT){// если температура ОЖ превысила порог, то выводим сообщение, каждые 4 секунды.
- if(time2+4000<= millis()){time2= millis(); stmp2[1]=(engTemp-40)*2.0; stmp2[2]=flag2; CAN2.sendMsgBuf(0x31B, 0, 8, stmp2);}
- }
- // секция сброса Driving ECO2
- if(time3 + 1000 < millis()){
- CAN2.readMsgBuf(&len2, rxBuf2); // Чтение данных: len = data length, buf = data byte(s)
- rxId2 = CAN2.getCanId(); //Получаем ID сообщения
- if(rxId2 == 0x31C && rxBuf2[2]==0x80){
- CAN1.sendMsgBuf(0x433, 0, 8, rxBuf2);
- time3 = millis();
- }
- }
- //Секция гироскопа
- mpuIntStatus = mpu.getIntStatus();
- // get current FIFO count
- fifoCount = mpu.getFIFOCount();
- // check for overflow (this should never happen unless our code is too inefficient)
- if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
- // reset so we can continue cleanly
- mpu.resetFIFO();
- // otherwise, check for DMP data ready interrupt (this should happen frequently)
- } else if (mpuIntStatus & 0x02) {
- // wait for correct available data length, should be a VERY short wait
- while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
- mpu.getFIFOBytes(fifoBuffer, packetSize);
- // track FIFO count here in case there is > 1 packet available
- // (this lets us immediately read more without waiting for an interrupt)
- fifoCount -= packetSize;
- // display Euler angles in degrees
- mpu.dmpGetQuaternion(&q, fifoBuffer);
- mpu.dmpGetGravity(&gravity, &q);
- mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
- if(timeMpu+DELAY_MPU <= millis()){
- timeMpu=millis();
- pitch = -ypr[1] * 180/M_PI;
- roll = ypr[2] * 180/M_PI;
- roll2 = roll*2-corroll*2;
- pitch2 = pitch*2-corpitch*2;
- if(roll2>60){roll2=60;}
- if(pitch2>40){pitch2=40;}
- if(roll2<-60){roll2=-60;}
- if(pitch2<-40){pitch2=-40;}
- info44[0]=0x78+roll2;
- info44[1]=0x78+pitch2;
- // отправляем pitch и roll
- CAN2.sendMsgBuf(0x407, 0, 8, info44);
- }
- }
- // секция кнопки
- switch( button1.Loop() ){
- case CLICK:
- if(flag3==1){flag3=0;}
- flag=flag+1;
- if(flag>4){
- flag=1;
- }
- stmp3[2]=flag2;
- if(flag==1){stmp3[3]=0x18;}
- if(flag==2){stmp3[3]=0x28;}
- if(flag==3){stmp3[3]=0x38;}
- if(flag==4){stmp3[3]=0x48;}
- CAN2.sendMsgBuf(0x31B, 0, 8, stmp3);
- refreshData2 = true;
- break;
- case DOUBLE_CLICK:
- if(flag3==0){flag3=1;}
- stmp3[2]=flag2;
- stmp3[3]=0x58;
- CAN2.sendMsgBuf(0x31B, 0, 8, stmp3);
- break;
- case LONG_CLICK:
- stmp3[2]=flag2;
- for (int i = 0; i < 113; i = i + 16){
- stmp3[3]=0x18+i;
- CAN2.sendMsgBuf(0x31B, 0, 8, stmp3);
- delay(100);
- }
- break;
- case LONG_CLICK_OFF:
- EEPROM.update(20,flag3);
- if(flag3==0){EEPROM.update(10,flag);}
- break;
- case AUTO_CLICK:
- corroll = roll;
- corpitch = pitch;
- EEPROM.put(address, corroll);
- address += sizeof(int);
- EEPROM.put(address, corpitch);
- address=0;
- stmp3[2]=flag2;
- for (int i = 0; i < 113; i = i + 16){
- stmp3[3]=0x18+i;
- CAN2.sendMsgBuf(0x31B, 0, 8, stmp3);
- delay(100);
- }
- break;
- }
- }
Add Comment
Please, Sign In to add comment