#1 2022-02-03 16:18:29

Medvedlovelist
Учасник
Зареєстрований: 2022-02-03
Повідомлень: 3

Помогите пожалуйста с ошибками в программе

#include <mcp_can_dfs.h>
#include <mcp_can.h>
#include <SPI.h>
#include <EEPROM.h>
#include <avr/sleep.h>
#include <avr/power.h>

// Красный провод – Vcc c +5 В, белый — RXD, зелёный – TXD, чёрный – GN

#define PinTX             0
#define PinRX             1
#define PinSDA            2
#define PinSCL            3
#define LED_Steer_Pin     8                               // Пин контрольного светодиода руля   (сине-черный)
#define freePin0          5
#define freePin1          6
#define serviceCanPin     7
#define LED_Glass_Pin     4                               // Пин контрольного светодиода стекла (бело-зеленый)
#define freePin2          9
#define DebugPin          10 
#define Button_Glass_Pin  11                              // Пин кнопкм стекла                  (черно-белый)
#define Button_Steer_Pin  12                              // Пин кнопки руля                    (сине-зеленый)
#define FreePin4          21
#define MCP_PORT          10
#define LedOnBoard        23

#define IRN_SDA           1                               // Прерывание для кнопки стекла
#define IRN_SCL           0                               // Прерывание для кнопки руля
#define IRN_UART_RX       2                               // Прерывание для Serial1. Не используется. Поставлено для порядка )).
#define IRN_UART_TX       3                               // Прерывание для Serial1. Используется для просыпания в режиме сна.  
#define IRN_CAN           4                               // Прерывание для CAN. Только для Leonardo Can Bus
#define PrintPort         Serial1
#define PrintBaud         115200

#define TimeInactivityMAX 20000                           // Максимально допустимое кол-во миллисекунд неактивности шины перед переходом в сон.
#define CanIDClimate      0x601                           // Порт СAN шины для управления обогревом 
#define CAN_ID_time       0x6B6                           // Порт СAN шины для отслеживания времени
#define carModeSleep        0                             // Режимы работы: все спят
#define carModeWake         1                             // Сняли с сигналки
#define carModeACC          2                             // Зажигание
#define carmodeEngine       3                             // Мотор работает
 
const int EE_Steer_Address = 0;                           // Адрес постоянного хранилища состояния обогрева руля
const int EE_Glass_Address = 1;                           // Адрес постоянного хранилища состояния обогрева стекла

boolean EE_Steer           = false;                       // Состояние руля    true - вкл, false - выкл
boolean EE_Glass           = false;                       // Состояния стекла  true - вкл, false - выкл
byte ADCSRA_OLD_SAVED;

MCP_CAN CAN(MCP_PORT);                                    // Инициализация порта CAN шины

unsigned char SteerOff[5]  = {0x20, 0x74, 0x00, 0x00, 0x00};   // КАН строка выключение руля
unsigned char SteerOn [5]  = {0x20, 0x74, 0x00, 0x01, 0x00};   // КАН строка включение руля
unsigned char GlassOff[4]  = {0x20, 0x6D, 0x00, 0x01};         // КАН строка выключение стекла
unsigned char GlassOn [4]  = {0x20, 0x6D, 0x01, 0x01};         // КАН строка включение стекла

unsigned char len = 0;										// Длина полученной строки
unsigned char buf[8];										// Буфер КАН шины
long timeLastCan      = 0;									// Время последнего обращения к шине

volatile boolean       flagRecv     = false;				// Флаг того, что сработало прерывание - получен сигнал по CAN шине.    
volatile boolean       flagAwake    = false;
volatile boolean       flagSleep    = false;				// Уснули 
volatile boolean       flagled      = false;
volatile boolean       flagNoDebug  = true;
volatile int           carMode      =

struct  BUTTON {											// структура кнопка
        boolean on;											// нажатие было
        boolean longpress;									// нажатие было длинным
      };

void setup() {
    PrintPort.begin(115200);								// Инициализация ком порта для контрольного вывода. В будущем, все строки Serial можно закомментировать
    while(!PrintPort) {
		delay(50);
		}
    while (CAN_OK != CAN.begin(CAN_500KBPS))  {            // Инициализация КАН шины : baudrate = 500k
        PrintPort.println("CAN BUS Shield init fail");
        PrintPort.println(" Init CAN BUS Shield again");
        delay(100);
    }

    ADCSRA_OLD_SAVED = ADCSRA;
    ADCSRA= 0;												// Выключение АЦП
    pinMode(Button_Glass_Pin,INPUT_PULLUP);					// Инициализация кнопки стекла
    pinMode(Button_Steer_Pin,INPUT_PULLUP);					// Инициализация кнопки руля
    pinMode(PinSDA, INPUT_PULLUP);							// порт под отладочное прерывание- вывод из сна  
    pinMode(LedOnBoard, OUTPUT);
    pinMode(LED_Glass_Pin, OUTPUT);
    pinMode(LED_Steer_Pin, OUTPUT);    
    digitalWrite(LedOnBoard, HIGH);
    pinMode(DebugPin, INPUT_PULLUP);
    flagNoDebug = (digitalRead(DebugPin)== HIGH);
    if (!flagNoDebug) PrintPort.println ("Debug mode");
    pinMode(DebugPin, OUTPUT);
    digitalWrite(DebugPin, LOW);   
    EE_Steer = EEPROM.read(EE_Steer_Address);				// Чтение из памяти состояние руля
    EE_Glass = EEPROM.read(EE_Glass_Address);				// Чтение из памяти состояние стекла
    attachInterrupt(4, ISR_CAN, FALLING);					// Инициализация прерывания по чтению из КАН шины 
    pinMode(PinSDA, INPUT_PULLUP);
    attachInterrupt (1, ISR_AWAKE, FALLING);				// отдадочное прерывание 
    CAN.init_Mask(0, 0, 0x7FF) ;							// there are 2 mask in mcp2515, you need to set both of them
    CAN.init_Mask(1, 0, 0x7FF);								// в оригинале стоит 0x3FF ?
    CAN.init_Filt(0, 0, CanIDClimate);						// маска порта, отвечающего за климат
    CAN.init_Filt(1, 0, CAN_ID_time);						// вторая маска - порт  времени
    timeLastCan = millis();
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);					// Здесь устанавливается режим сна
    PrintPort.println("**************************************");
    Steer ();												// Инициализация обогревов из памяти  
    Glass ();
    PrintPort.println("*     Setup OK . ver. 06-11 21:      *");
    PrintPort.println("**************************************");
}
void Glass() {												// Подпрограмма управление стеклом
  if (EE_Glass) {											// Если флаг стекла установлен   
    CAN.sendMsgBuf(CanIDClimate, 0, 4, GlassOn);			// Посылка команды включение обогрева стекла
    digitalWrite(LED_Glass_Pin,HIGH);						// Включение светодиода стекла  
    PrintPort.println("  Glass On");
    }
  else {                                                  // Иначе - флаг обогрева сброшен
    CAN.sendMsgBuf(CanIDClimate, 0, 4, GlassOff);         // Посылка команды выключение обогрева стекла
    digitalWrite(LED_Glass_Pin,LOW);                      // Выключение светодиода стекла  
    PrintPort.println("  Glass off");
    }
  delay(200);  
}
void ISR_CAN() {                                           // Обработка прерывания шины.
    sleep_disable();
    flagRecv = true;
}
void ISR_AWAKE() {
    sleep_disable();
    flagAwake =  true;
}
boolean timetoSleep() {                                   // Проверка того не пора ли ложиться спать 
    int time = millis() - timeLastCan;                    // сколько времени прошло с тех пор, как что то получали
    if (time<0) timeLastCan = millis();                   // Если было переполнение времени - обновляем счетчик времени   
    return (time > TimeInactivityMAX)&&flagNoDebug;       // Если давно не получали ничего по шине то надо спать и нет отладки  
} 
void sleepNow()  {                                        // функциия ухода в спячку(
    PrintPort.println("Sleep mode ");                     // отладка   
    digitalWrite(LED_Glass_Pin,LOW);                      // Выключение светодиода руля
    digitalWrite(LED_Steer_Pin,LOW);                      // Выключение светодиода стекла
    digitalWrite(LedOnBoard, LOW);
    flagSleep = true; 
	  USBDevice.detach();										//  Выключаем USB
    delay(50);
/*    pinMode(Button_Glass_Pin, OUTPUT);
    pinMode(Button_Steer_Pin, OUTPUT);
    digitalWrite(Button_Glass_Pin, LOW);
    digitalWrite(Button_Steer_Pin, LOW);   
*/
    delay(100);                                           // Этот делэй необходим, чтоб функция sleep не вызывала ошибку по Serial
    sleep_enable();                                       // Включаем sleep-бит в регистре mcucr. Теперь возможен слип
    sleep_mode();                                         // Здесь устройство перейдет в режим сна!!!
// -----------------------------------------------ПОСЛЕ ПРОСЫПАНИЯ ВЫПОЛНЕНИЕ КОДА ПРОДОЛЖИТСЯ ОТСЮДА!!! ????
} 
void wakeNow() {                                          // Просыпаемся из спящего режима
	USBDevice.attach();                               //  Выключаем USB
    digitalWrite(LedOnBoard, HIGH);                       // Зажигаем обратно светодиод                        
//    pinMode(Button_Glass_Pin, INPUT_PULLUP);
//    pinMode(Button_Steer_Pin, INPUT_PULLUP);
    delay(100);
    flagSleep = false;                                    // Выключаем спящий статус 
    Steer();
    Glass();
    timeLastCan     = millis();                           // Время последнего полученного сообщенияо шине. 
    PrintPort.println("Awake");        
    flagAwake       = false;                              // Проснулись полностью, флаг прячем
}  
void Steer() {                                            // Подпрограмма управление рулем
  if (EE_Steer)                                           // Если флаг обогрева установлен
    {
     CAN.sendMsgBuf(CanIDClimate, 0, 5, SteerOn);          // Посылка команды включения обогрева руля 
     digitalWrite(LED_Steer_Pin,HIGH);                     // Включение светодиода руля  
     PrintPort.println("  Steer on");
    }
  else                                                     // Иначе - флаг обогрева сброшен
    {
    CAN.sendMsgBuf(CanIDClimate, 0, 5, SteerOff);                  // Посылка команды вкылючения обогрева руля 
    digitalWrite(LED_Steer_Pin,LOW);                       // Выключение светодиода руля  
    PrintPort.println("  Steer off");
     }
  delay(200);    
} 
void Blink(int pin, int n, boolean led)                    // Подпрограмма "Моргание светодиодом в подтверждение". Номер пина, количество морганий, статус в котором надо оставить.  
{
     if (led)                                              // если светодиод уже горит, то выключаем
     {
      digitalWrite(pin,LOW);
      delay (500);
     }
     for (int i=0; i<n; i++)
         {                                                 // n  раз моргнули в подтверждение
          digitalWrite(pin,HIGH);
          delay (500);
          digitalWrite(pin,LOW);
          delay (500);
         }
     if (led) digitalWrite(pin,HIGH);                      // Включили светодиод обратно, если надо.  
}

ВОТ ЗДЕСЬ ВЫДАЕТ ОШИБКУ BUTTON Pressing(int pin)                 [/color][/s]                 // Подпрограмма обработка нажатия кнопки. Pin - номер порта
{
   int n = 0;                                              // Счетчик
   BUTTON key;                                             // Структура кнопки для возврата
   while (digitalRead(pin)==LOW && n <=100)                // Обрабатывет длинное нажатие, считает тайминги, выход, если превышен таймиг или кнопка отпущена 
     {
      n++;                                                 // Увеличение счетчика тайминга
      delay (20);
     }
  key.on = (n>0&& n<100);                                  // Установлен флаг короткого нажатия
  key.longpress = (n>=100);                                // Установлен флаг длинное нажатие  
  return key;      
}

void KeyDetect()                                           // Подпрограмма чтения кнопки
{
  BUTTON glass = Pressing (Button_Glass_Pin);              // Чтение нажатия кнопки стекла
  BUTTON steer = Pressing (Button_Steer_Pin);              // Чтение нажатия кнопки руля
  if (steer.longpress)                                     // ОБработка длинного нажатия кнопки руля
     {
     EEPROM.write (EE_Steer_Address,EE_Steer);             // Запись текущего состояния в EEPROM
     PrintPort.write("Steer to ROM");
     Blink (LED_Steer_Pin, 5, EE_Steer);                   // Моргнуть 5 раз и оставить в том же положении, что был
     delay (500);
     }
   if (glass.longpress)                                    // ОБработка длинного нажатия кнопки стекла
     {
     EEPROM.write (EE_Glass_Address,EE_Glass);             // Запись текущего состояния в EEPROM
     PrintPort.write("Glass to ROM");
     Blink (LED_Glass_Pin, 5, EE_Glass);                   // Моргнуть 5 раз и оставить в том же положении, что был  
     delay(500);
     }               
   if (steer.on)                                           // ОБработка простого нажатия кнопки руля
     {    
      EE_Steer = !EE_Steer;                                // Меняем значение флага обогрева руля на противоположное 
      Steer ();                                            // Отправляем на обработку с текушщим значением                       
      } 
    if (glass.on)                                          // ОБработка простого нажатия кнопки стекла                                               
     {    
      EE_Glass = !EE_Glass;                                // Обращаем значение обогрева стекла
      Glass();                                             // Отправляем на обработку с текушщим значением
     } 
}
void readCAN() {											// ОБработка перехвата внешнего воздействия через КАН шину 
  flagRecv=0;
  timeLastCan = millis();
  boolean steer_on = true, steer_off = true;               // Инициализация ключей проверки строки  
  boolean glass_on = true, glass_off = true;     
  while (CAN_MSGAVAIL == CAN.checkReceive())                // Взято из примера, очищение буфера                 
    {
    CAN.readMsgBuf(&len, buf);                              // Чтение данных из буфера КАН.  Данные - len: data length, buf: data buf
    if ((len==5)&&(CAN.getCanId()==CanIDClimate)) {                 // Если длина строки == 5, то это руль
        for(int i = 0; i<len; i++) {          
           steer_on  = steer_on  && (buf[i]==SteerOn [i]);  // Сравниваем побитово на совпадение со сторокй включения руля
           steer_off = steer_off && (buf[i]==SteerOff[i]);  // Сравниваем побитово на совпадение со строкой выключения руля
           }
        if (steer_on) {                                     // Если перехвачена команда включения руля               
           EE_Steer = true;                                 // Установка флага -подогрев руля включен
           digitalWrite(LED_Steer_Pin,HIGH);                // Включение светодиода руля  
           PrintPort.println("  External steer on");
           }
        else if (steer_off) {                               // Если перехвачена команды выключения руля            
           EE_Steer = false;                                // Установка флага - подогрев руля выключен 
           digitalWrite(LED_Steer_Pin,LOW);                 // Выключение светодиода руля  
           PrintPort.println("  External steer off");
            }
        else PrintPort.println("  Steer unknown command");
        }
    else if ((len==4)&&(CAN.getCanId()==CanIDClimate)) {    // Если длина строки == 4, ьо это стекло      
        for(int i = 0; i<len; i++) {        
           glass_on  = glass_on  && (buf[i]==GlassOn [i]);  // Сравниваем побитово на совпадение со строкой включения стекла 
           glass_off = glass_off && (buf[i]==GlassOff[i]);  // Сравниваем побитово на совпадение со строкой вылючения стекла
           }
        if (glass_on) {                                     // Если перехвачена команда включения стекла         
           EE_Glass = true;                                 // Установка флага включения стекла 
           digitalWrite(LED_Glass_Pin,HIGH);                // Включение светодиода стекла  
           PrintPort.println("  External glass on");
           }
        else if (glass_off) {                               // Если перехвачена команда включения стекла        
           EE_Glass = false;                                // Установка флага выключения стекла
           digitalWrite(LED_Glass_Pin,LOW);                 // Выключение светодиода стекла  
           PrintPort.println("  External glass off");
           }   
        else PrintPort.println("  Glass unknown command");
        }                                                   // Конец распознавания
    }                                                       // Конец цикла чтения из буфера           
}
void loop()  {                                              // Основной цикл    
  if (flagSleep && (flagAwake || flagRecv )) {
        flagAwake = false;
        flagRecv  = false;
        wakeNow();                                          // Если команда на просыпание
      }
   if (!flagSleep) {
      if (flagRecv) readCAN();                              // Что то получили по шине
      if (timetoSleep()) sleepNow();
      KeyDetect();                                          // ОБработка нажатия клавиши
   }
}


/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

Остання редакція Medvedlovelist (2022-02-03 16:19:41)

Неактивний

#2 2022-02-03 16:20:41

Medvedlovelist
Учасник
Зареєстрований: 2022-02-03
Повідомлень: 3

Re: Помогите пожалуйста с ошибками в программе

В подпрограмме обработки нажатия кнопок выдает ошибку (
Что не так?

Неактивний

#3 2022-02-03 16:24:00

Medvedlovelist
Учасник
Зареєстрований: 2022-02-03
Повідомлень: 3

Re: Помогите пожалуйста с ошибками в программе

“Button” does not name a type

Неактивний

#4 2022-02-03 16:42:30

Honey
Учасник
З Київ
Зареєстрований: 2020-09-26
Повідомлень: 433

Re: Помогите пожалуйста с ошибками в программе

Или сделайте тип:

typedef struct {
 boolean on;
 boolean longpress;
} BUTTON;

Или пишите везде struct BUTTON

Активний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму