Arduino LED控制器在启动时挂起

时间:2017-11-03 06:29:45

标签: arduino

我试图编写一个通过PWM控制强度的LED控制器。然而,我的问题是,我甚至无法进入循环部分,它似乎在我宣布我的课时挂起。我已经尝试检查我班上的任何功能是否导致问题,但由于我甚至无法循环,所以课堂上肯定有问题。我已经写完了这个课程并将其放入一个名为LED的图书馆。

代码有点长,但现在是:

#ifndef LED_H
#define LED_H

#include <LiquidCrystal.h>
#include <Button.h>
#include <EEPROM.h>
#include <TimeLib.h>
#include <PWM.h>

class LED
{
public:

    LED();
    int read_encoder(); //Reads rotary encoder
    void clearLCD();
    void setAllLed();
    void printLCD();
    void setOneLed(int);
    int   setLed(int,         // current time in minutes
                 int,        // pin for this channel of LEDs
                 int,         // start time for this channel of LEDs
                 int,        // photoperiod for this channel of LEDs
                 int,          // fade duration for this channel of LEDs
                 int,        // max value for this channel
                 bool   // true if the channel is inverted
                );
    void menuWizard();
    int subMenuWizard(int, int, bool, bool);
    void displayMainMenu();
    void printMins(int, bool);
    void printHMS(byte,byte,byte);
    long EEPROMReadlong(long);
    void EEPROMWritelong(int, long);
    bool pressSelect();
    bool pressBack();
    void rotateCheck(int&, int, int);

    //variables for the LED channels
    int minCounter = 0;         // counter that resets at midnight.
    int oldMinCounter = 0;      // counter that resets at midnight.

    int ledPins[5]={2,3,5,6,7};

    int ledVal[5]={0,0,0,0,0};

    // Variables making use of EEPROM memory:
    int variablesList[20];

    bool invertedLEDs[5]={false,false,false,false,false};

    //Backlight Variables
    unsigned long backlightIdleMs = 0;




private:
};

#endif // LED_H

这是.cpp文件:

            #define LCD_RS 35        // RS pin
            #define LCD_ENABLE 34    // enable pin
            #define LCD_DATA4 33     // d4 pin
            #define LCD_DATA5 32     // d5 pin
            #define LCD_DATA6 31    // d6 pin
            #define LCD_DATA7 30     // d7 pin
            #define LCD_BACKLIGHT 9 // backlight pin

            // Backlight config
            #define BACKLIGHT_DIM 10              // PWM value for backlight at idle
            #define BACKLIGHT_ON 70               // PWM value for backlight when on
            #define BACKLIGHT_IDLE_MS 10000 // Backlight idle delay

            #define ENC_A 14
            #define ENC_B 15
            #define ENC_PORT PINC

            #include <LiquidCrystal.h>
            #include <Button.h>
            #include <EEPROM.h>
            #include <TimeLib.h>
            #include <PWM.h>
            #include "LED.h"


            LiquidCrystal lcd(LCD_RS, LCD_ENABLE, LCD_DATA4, LCD_DATA5, LCD_DATA6, LCD_DATA7);
            Button goBack=Button(12, PULLDOWN);
            Button select=Button(13, PULLDOWN);


            LED::LED()
            {
            InitTimersSafe();

            pinMode(LCD_BACKLIGHT, OUTPUT);
              lcd.begin(16, 2);
              digitalWrite(LCD_BACKLIGHT, HIGH);
              lcd.print("sEx LED, V1");
              clearLCD();
              delay(5000);
              analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);

             if (variablesList[0] > 1440 || variablesList[0] < 0) {
                        variablesList[0] = 720;      // minute to start this channel.
                        variablesList[1] = 400;    // photoperiod in minutes for this channel.
                        variablesList[2] = 100;                       // max intensity for this channel, as a percentage
                        variablesList[3] = 100;  // duration of the fade on and off for sunrise and sunset for
                        //    this channel.
                        variablesList[4] = 720;
                        variablesList[5] = 400;
                        variablesList[6] = 100;
                        variablesList[7] = 100;

                        variablesList[8] = 720;
                        variablesList[9] = 400;
                        variablesList[10] = 100;
                        variablesList[11] = 100;

                        variablesList[12] = 720;
                        variablesList[13] = 400;
                        variablesList[14] = 100;
                        variablesList[15] = 100;

                        variablesList[16] = 720;
                        variablesList[17] = 400;
                        variablesList[18] = 100;
                        variablesList[19] = 100;

                }

                else {

                     variablesList[0] = EEPROMReadlong(0);      // minute to start this channel.
                     variablesList[1] = EEPROMReadlong(4);    // photoperiod in minutes for this channel.
                     variablesList[2] = EEPROMReadlong(8);                      // max intensity for this channel, as a percentage
                     variablesList[3] = EEPROMReadlong(12);  // duration of the fade on and off for sunrise and sunset for
                                                                //    this channel.
                     variablesList[4] = EEPROMReadlong(16);
                     variablesList[5] = EEPROMReadlong(20);
                     variablesList[6] = EEPROMReadlong(24);
                     variablesList[7] = EEPROMReadlong(28);

                     variablesList[8] = EEPROMReadlong(32);
                     variablesList[9] = EEPROMReadlong(36);
                     variablesList[10] = EEPROMReadlong(40);
                     variablesList[11] = EEPROMReadlong(44);

                     variablesList[12] = EEPROMReadlong(48);
                     variablesList[13] = EEPROMReadlong(52);
                     variablesList[14] = EEPROMReadlong(56);
                     variablesList[15] = EEPROMReadlong(60);

                     variablesList[16] = EEPROMReadlong(64);
                     variablesList[17] = EEPROMReadlong(68);
                     variablesList[18] = EEPROMReadlong(72);
                     variablesList[19] = EEPROMReadlong(76);

                }

            }


            void LED::printLCD(){lcd.print("test");clearLCD();delay(2000);lcd.print("testing");clearLCD();}

            bool LED::pressSelect(){

                if (select.uniquePress()){return 1;}

                else {return 0;}


            }
            bool LED::pressBack(){

                if (goBack.uniquePress()){return 1;}

                else {return 0;}


            }

            void LED::clearLCD(){

            lcd.clear();

            }

            void LED::displayMainMenu(){

                oldMinCounter = minCounter;
                minCounter = hour() * 60 + minute();

                for (int i=0;i<17;i=i+4){

                     if (variablesList[i+3] > variablesList[i+1] / 2 && variablesList[i+1] > 0) {
                        variablesList[i+3] = variablesList[i+1] / 2;
                     }
                    if (variablesList[i+3] < 1) {
                        variablesList[i+3] = 1;
                    }

                }




              //check & set any time functions

               if (minCounter > oldMinCounter) {
                  lcd.clear();
                }
                lcd.setCursor(0, 0);
                printHMS(hour(), minute(), second());
                lcd.setCursor(0, 1);
                lcd.print(ledVal[0]);
                lcd.setCursor(4, 1);
                lcd.print(ledVal[1]);
                lcd.setCursor(8, 1);
                lcd.print(ledVal[2]);


            }

            int LED::read_encoder()
            {
              static int enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
              static int old_AB = 0;
              /**/
              old_AB <<= 2;                   //remember previous state
              old_AB |= ( ENC_PORT & 0x03 );  //add current state
              return ( enc_states[( old_AB & 0x0f )]);
            }

            int LED::setLed(int mins,         // current time in minutes
                         int ledPin,        // pin for this channel of LEDs
                         int start,         // start time for this channel of LEDs
                         int period,        // photoperiod for this channel of LEDs
                         int fade,          // fade duration for this channel of LEDs
                         int ledMax,        // max value for this channel
                         bool inverted   // true if the channel is inverted
                        )  {
              int val = 0;

              //fade up
              if (mins > start || mins <= start + fade)  {
                val = map(mins - start, 0, fade, 0, ledMax);
              }
              //fade down
              if (mins > start + period - fade && mins <= start + period)  {
                val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
              }
              //off or post-midnight run.
              if (mins <= start || mins > start + period)  {
                if ((start + period) % 1440 < start && (start + period) % 1440 > mins )
                {
                  val = map((start + period - mins) % 1440, 0, fade, 0, ledMax);
                }
                else
                  val = 0;
              }


              if (val > ledMax)  {
                val = ledMax;
              }
              if (val < 0) {
                val = 0;
              }

              if (inverted) {
                pwmWrite(ledPin, map(val, 0, 100, 255, 0));
              }
              else {
                pwmWrite(ledPin, map(val, 0, 100, 0, 255));
              }
              return val;
            }

            void LED::printMins(int mins,       //time in minutes to print
                           bool ampm    //print am/pm?
                          )  {
              int hr = (mins % 1440) / 60;
              int mn = mins % 60;
              if (hr < 10) {
                lcd.print(" ");
              }
              lcd.print(hr);
              lcd.print(":");
              if (mn < 10) {
                lcd.print("0");
              }
              lcd.print(mn);
            }

            void LED::printHMS (byte hr,
                           byte mn,
                           byte sec      //time to print
                          )
            {

              if (hr < 10) {
                lcd.print(" ");
              }
              lcd.print(hr, DEC);
              lcd.print(":");
              if (mn < 10) {
                lcd.print("0");
              }
              lcd.print(mn, DEC);
              lcd.print(":");
              if (sec < 10) {
                lcd.print("0");
              }
              lcd.print(sec, DEC);
            }

            //EEPROM write functions
            long LED::EEPROMReadlong(long address)
            {
              //Read the 4 bytes from the eeprom memory.
              long four = EEPROM.read(address);
              long three = EEPROM.read(address + 1);
              long two = EEPROM.read(address + 2);
              long one = EEPROM.read(address + 3);

              //Return the recomposed long by using bitshift.
              return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
            }

            void LED::EEPROMWritelong(int address, long value)
            {
              //Decomposition from a long to 4 bytes by using bitshift.
              //One = Most significant -> Four = Least significant byte
              byte four = (value & 0xFF);
              byte three = ((value >> 8) & 0xFF);
              byte two = ((value >> 16) & 0xFF);
              byte one = ((value >> 24) & 0xFF);

              //Write the 4 bytes into the eeprom memory.
              EEPROM.write(address, four);
              EEPROM.write(address + 1, three);
              EEPROM.write(address + 2, two);
              EEPROM.write(address + 3, one);
            }

            void LED::setAllLed(){

                int j=0;

                for (int i=0;i<17;i=i+4){

                    int a=i;int b=i+1;int c=i+2;int d=i+3;

                    ledVal[j] = setLed(minCounter, ledPins[j], variablesList[a], variablesList[b], variablesList[c], variablesList[d], invertedLEDs[j]);
                    j++;

                }

            }

            void LED::setOneLed(int channel){

                int j=channel;
                int i=0;

                if(channel==1){i+=4;}
                if(channel==2){i+=8;}
                if(channel==3){i+=12;}
                if(channel==4){i+=16;}

                int a=i;int b=i+1;int c=i+2;int d=i+3;

                ledVal[j] = setLed(minCounter, ledPins[j], variablesList[a], variablesList[b], variablesList[c], variablesList[d], invertedLEDs[j]);



            }

            void LED::rotateCheck(int& menuCount, int minMenu, int maxMenu){

                while (menuCount!=0){

                    int rotateCount;
                    rotateCount=read_encoder();

                  if (rotateCount) {

                      menuCount+=rotateCount;

                      if (menuCount<minMenu){menuCount==maxMenu;}
                      if (menuCount>maxMenu){menuCount==minMenu;}

                    clearLCD();
                    }
                }

            }

            void LED::menuWizard(){

                int menuCount=1;
                String menuList[6]={"Time","LED Max","LED Start","LED End","Fade Length","Ch Override"};
                String channelList[5]={"1","2","3","4","5"};



                while (menuCount!=0){

                   rotateCheck(menuCount,1,6);

                    lcd.setCursor(0, 0);
                    lcd.print(menuList[menuCount-1]);
                    clearLCD();

                    if (goBack.isPressed()){

                        menuCount=0;

                    }

                    if (pressSelect() && menuCount!=0){

                        int timeMode=1;
                        int channelCount=0;
                        bool goBack=0;

                        while (goBack!=1){

                            if (menuCount==1){

                                if (pressSelect()){

                                    timeMode++;

                                    if (timeMode>2){timeMode=1;}

                                }

                                int timeAdjDetect=read_encoder();

                                if (timeMode==1){

                                    if (timeAdjDetect){

                                        if (timeAdjDetect>0){adjustTime(SECS_PER_HOUR);}
                                        if (timeAdjDetect<0) {adjustTime(-SECS_PER_HOUR);}

                                    }

                                    lcd.setCursor(0, 0);
                                    lcd.print("Set Time: Hrs");
                                    lcd.setCursor(0, 1);
                                    printHMS(hour(), minute(), second());

                                }

                                else{

                                    if (timeAdjDetect){

                                        if (timeAdjDetect>0){adjustTime(SECS_PER_MIN);}
                                        if (timeAdjDetect<0) {adjustTime(-SECS_PER_MIN);}

                                    }

                                    lcd.setCursor(0, 0);
                                    lcd.print("Set Time: Mins");
                                    lcd.setCursor(0, 1);
                                    printHMS(hour(), minute(), second());

                                }

                                clearLCD();

                            }

                            else{

                                rotateCheck(channelCount,0,4);

                                lcd.setCursor(0,0);
                                lcd.print("Select Channel");
                                lcd.setCursor(0,1);
                                lcd.print(channelList[channelCount]);
                                clearLCD();

                                if (pressSelect()){

                                    if (menuCount==2){

                                        subMenuWizard(2,channelCount,0,0);

                                    }

                                    if (menuCount==3){

                                        subMenuWizard(0,channelCount,1,0);

                                    }

                                    if (menuCount==4){

                                        subMenuWizard(1,channelCount,1,1);

                                    }

                                    if (menuCount==5){

                                        subMenuWizard(3,channelCount,1,0);

                                    }

                                }


                            }

                                if (pressBack()){goBack=1;}

                            }

                    }


                }




                for (int i=0;i<20;i++){

                    int j=0;

                    EEPROMWritelong(j, variablesList[i]);

                    j+=4;

                }

            }

            int LED::subMenuWizard(int i, int channel, bool time, bool truetime){

                if (channel==1){i=i+4;}
                if (channel==2){i=i+8;}
                if (channel==3){i=i+12;}
                if (channel==4){i=i+16;}

                while (!pressBack()){

                    if (time==0){

                        rotateCheck(variablesList[i],0,100);

                        lcd.setCursor(0,0);
                        lcd.print("Set:");
                        lcd.setCursor(0,1);
                        lcd.print(variablesList[i]);

                        setOneLed(channel);
                        clearLCD();

                    }

                    else{

                        if (truetime){

                        rotateCheck(variablesList[i],0,1439);

                        lcd.setCursor(0,0);
                        lcd.print("Set:");
                        lcd.setCursor(0,1);
                        printMins(variablesList[i] + variablesList[i-1], true);
                        clearLCD();

                        }

                        else {

                            rotateCheck(variablesList[i],0,1439);

                            lcd.setCursor(0,0);
                            lcd.print("Set:");
                            lcd.setCursor(0,1);
                            printMins(variablesList[i], true);
                            clearLCD();

                        }

                        setOneLed(channel);

                    }


                }



            }

最后是.ino文件:

    #define LCD_BACKLIGHT 9 // backlight pin
    #define BACKLIGHT_DIM 10              // PWM value for backlight at idle
    #define BACKLIGHT_ON 70               // PWM value for backlight when on
    #define BACKLIGHT_IDLE_MS 10000 // Backlight idle delay


    #include <LED.h>


    //Initialize buttons
    int buttonCount = 1;

    LED main;

    void setup() {


    };

    void loop() {
     /* main.setAllLed();

      //turn the backlight off and reset the menu if the idle time has elapsed
      if (main.backlightIdleMs + BACKLIGHT_IDLE_MS < millis() && main.backlightIdleMs > 0 ) {
       analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);
      main.clearLCD();
      main.backlightIdleMs = 0;
      }



      if (buttonCount == 1) {

        main.displayMainMenu();

      }

      if (buttonCount == 2) {

        main.menuWizard();
        buttonCount = 1;

      }


    */
    main.printLCD();
    };

另外,在循环部分,我已经评论了要运行的代码部分,并且我正在运行一个函数来测试我是否已成功进入循环印刷&#34;测试&#34;在屏幕上。

我正在使用Mega。

1 个答案:

答案 0 :(得分:1)

LED::LED()
            {
            InitTimersSafe();

            pinMode(LCD_BACKLIGHT, OUTPUT);
              lcd.begin(16, 2);
              digitalWrite(LCD_BACKLIGHT, HIGH);
              lcd.print("sEx LED, V1");
              clearLCD();
              delay(5000);
              analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);

您必须了解此构造函数在创建对象时运行,并且可能在从main运行init()之前运行。因此硬件在那时还没有准备好,pinMode和digitalWrite以及东西都没有用。液晶代码无法真正在那里工作,我打赌这是悬挂东西的部分。

构造函数应该只执行初始化变量之类的操作。任何依赖于硬件的代码都应该进入begin()或init()或者一旦安全地执行这些操作就可以从setup中调用的任何方法。 Serial对象是另一个必须执行此操作的类的一个很好的示例。