关于1602屏灯控制的问题-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1267|回复: 23

[未解决] 关于1602屏灯控制的问题

[复制链接]
发表于 2022-3-9 21:32 | 显示全部楼层 |阅读模式
用Arduino nano板 D8口输出控制1602LCD的背光,当旋转编码开关时,屏灯自动亮起,延时N秒后熄屏,我是直接在编码开关的引脚上取高电平信号到arduino的D10脚,目前遇到的问题:编码开关的引脚是高低电平相邻分布的,当编码开关停留在高电平档时,屏无法自动熄灭,求解决办法,谢谢;
发表于 2022-3-9 23:59 | 显示全部楼层
if(编码开关转动)
记录时间
亮屏
if(时间超时延时时间)
熄屏
发表于 2022-3-10 05:51 | 显示全部楼层
用外部中断来控制1602LCD的背光,当旋转编码开关时触发中断来实现。
 楼主| 发表于 2022-3-10 08:34 来自手机 | 显示全部楼层
lwq1947 发表于 2022-3-10 05:51
用外部中断来控制1602LCD的背光,当旋转编码开关时触发中断来实现。

应该是不行哦,编码开关停留在高电平,还是会长亮的
发表于 2022-3-10 13:46 | 显示全部楼层
本帖最后由 lwq1947 于 2022-3-10 13:49 编辑
xgm1818 发表于 2022-3-10 08:34
应该是不行哦,编码开关停留在高电平,还是会长亮的

中断是电平变化时才触发,与编码开关静止时的电平无关。用中断程序来控制时间长短。
 楼主| 发表于 2022-3-12 13:25 | 显示全部楼层
lwq1947 发表于 2022-3-10 13:46
中断是电平变化时才触发,与编码开关静止时的电平无关。用中断程序来控制时间长短。 ...

我查了下NANO的中断口是2,3脚,这两个口目前已经占用了,还有没有其它方法;
发表于 2022-3-13 05:41 | 显示全部楼层
xgm1818 发表于 2022-3-12 13:25
我查了下NANO的中断口是2,3脚,这两个口目前已经占用了,还有没有其它方法; ...

把程序贴出来.
 楼主| 发表于 2022-3-13 20:12 | 显示全部楼层
  1. #include <SI4735.h>
  2. #include <EEPROM.h>
  3. #include <LiquidCrystal.h>
  4. #include "Rotary.h"
  5. #include "patch_init.h" // SSB patch for whole SSBRX initialization string

  6. const uint16_t size_content = sizeof ssb_patch_content; // see patch_init.h

  7. #define FM_BAND_TYPE 0
  8. #define MW_BAND_TYPE 1
  9. #define SW_BAND_TYPE 2
  10. #define LW_BAND_TYPE 3

  11. #define RESET_PIN 9

  12. // Enconder PINs
  13. #define ENCODER_PIN_A 2
  14. #define ENCODER_PIN_B 3

  15. // LCD 16x02 or LCD20x4 PINs
  16. #define LCD_D7 4
  17. #define LCD_D6 5
  18. #define LCD_D5 6
  19. #define LCD_D4 7
  20. #define LCD_RS 12
  21. #define LCD_E 13

  22. // Buttons controllers
  23. #define ENCODER_PUSH_BUTTON 14 // Pin A0/14
  24. #define DUMMY_BUTTON 15

  25. #define MIN_ELAPSED_TIME 300
  26. #define MIN_ELAPSED_RSSI_TIME 500
  27. #define ELAPSED_COMMAND 3000
  28. #define ELAPSED_CLICK 1500  
  29. #define DEFAULT_VOLUME 40   

  30. #define FM 0
  31. #define LSB 1
  32. #define USB 2
  33. #define AM 3
  34. #define LW 4

  35. #define SSB 1

  36. #define EEPROM_SIZE        512

  37. #define STORE_TIME 10000 // Time of inactivity to make the current receiver status writable (10s / 10000 milliseconds).

  38. // EEPROM - Stroring control variables
  39. const uint8_t app_id = 31; // Useful to check the EEPROM content before processing useful data
  40. const int eeprom_address = 0;
  41. long storeTime = millis();

  42. bool itIsTimeToSave = false;

  43. bool bfoOn = false;
  44. bool ssbLoaded = false;

  45. int8_t agcIdx = 0;
  46. uint8_t disableAgc = 0;
  47. int8_t agcNdx = 0;
  48. int8_t softMuteMaxAttIdx = 4;
  49. int8_t avcIdx;   // min 12 and max 90
  50. uint8_t countClick = 0;

  51. uint8_t seekDirection = 1;

  52. bool cmdBand = false;
  53. bool cmdVolume = false;
  54. bool cmdAgc = false;
  55. bool cmdBandwidth = false;
  56. bool cmdStep = false;
  57. bool cmdMode = false;
  58. bool cmdMenu = false;
  59. bool cmdRds  =  false;
  60. bool cmdSoftMuteMaxAtt = false;
  61. bool cmdAvc = false;


  62. bool fmRDS = false;

  63. int16_t currentBFO = 0;
  64. long elapsedRSSI = millis();
  65. long elapsedButton = millis();
  66. long elapsedCommand = millis();
  67. long elapsedClick = millis();
  68. volatile int encoderCount = 0;
  69. uint16_t currentFrequency;
  70. uint16_t previousFrequency = 0;


  71. const uint8_t currentBFOStep = 10;

  72. const char * menu[] = {"Volume", "FM RDS", "Step", "Mode", "BFO", "BW", "AGC/Att", "SoftMute", "AVC", "Seek Up", "Seek Down"};
  73. int8_t menuIdx = 0;
  74. const int lastMenu = 10;
  75. int8_t currentMenuCmd = -1;

  76. typedef struct
  77. {
  78.   uint8_t idx;      // SI473X device bandwidth index
  79.   const char *desc; // bandwidth description
  80. } Bandwidth;

  81. int8_t bwIdxSSB = 4;
  82. const int8_t maxSsbBw = 5;
  83. Bandwidth bandwidthSSB[] = {
  84.   {4, "0.5"},
  85.   {5, "1.0"},
  86.   {0, "1.2"},
  87.   {1, "2.2"},
  88.   {2, "3.0"},
  89.   {3, "4.0"}
  90. };


  91. int8_t bwIdxAM = 4;
  92. const int8_t maxAmBw = 6;
  93. Bandwidth bandwidthAM[] = {
  94.   {4, "1.0"},
  95.   {5, "1.8"},
  96.   {3, "2.0"},
  97.   {6, "2.5"},
  98.   {2, "3.0"},
  99.   {1, "4.0"},
  100.   {0, "6.0"}
  101. };

  102. int8_t bwIdxFM = 0;
  103. const int8_t maxFmBw = 4;

  104. Bandwidth bandwidthFM[] = {
  105.     {0, "AUT"}, // Automatic - default
  106.     {1, "110"}, // Force wide (110 kHz) channel filter.
  107.     {2, " 84"},
  108.     {3, " 60"},
  109.     {4, " 40"}};



  110. int tabAmStep[] = {1,    // 0
  111.                    5,    // 1
  112.                    9,    // 2
  113.                    10,   // 3
  114.                    50,   // 4
  115.                    100}; // 5

  116. const int lastAmStep = (sizeof tabAmStep / sizeof(int)) - 1;
  117. int idxAmStep = 3;

  118. int tabFmStep[] = {5, 10, 20};
  119. const int lastFmStep = (sizeof tabFmStep / sizeof(int)) - 1;
  120. int idxFmStep = 1;

  121. uint16_t currentStepIdx = 1;


  122. const char *bandModeDesc[] = {"FM ", "LSB", "USB", "AM "};
  123. uint8_t currentMode = FM;

  124. /**
  125. *  Band data structure
  126. */
  127. typedef struct
  128. {
  129.   const char *bandName;   // Band description
  130.   uint8_t bandType;       // Band type (FM, MW or SW)
  131.   uint16_t minimumFreq;   // Minimum frequency of the band
  132.   uint16_t maximumFreq;   // maximum frequency of the band
  133.   uint16_t currentFreq;   // Default frequency or current frequency
  134.   int8_t currentStepIdx;  // Idex of tabStepAM:  Defeult frequency step (See tabStepAM)
  135.   int8_t bandwidthIdx;    // Index of the table bandwidthFM, bandwidthAM or bandwidthSSB;
  136.   uint8_t disableAgc;
  137.   int8_t agcIdx;
  138.   int8_t agcNdx;
  139.   int8_t avcIdx;
  140. } Band;

  141. /*
  142.    Band table
  143.    YOU CAN CONFIGURE YOUR OWN BAND PLAN. Be guided by the comments.
  144.    To add a new band, all you have to do is insert a new line in the table below. No extra code will be needed.
  145.    You can remove a band by deleting a line if you do not want a given band.
  146.    Also, you can change the parameters of the band.
  147.    ATTENTION: You have to RESET the eeprom after adding or removing a line of this table.
  148.               Turn your receiver on with the encoder push button pressed at first time to RESET the eeprom content.  
  149. */
  150. Band band[] = {
  151.     {"VHF", FM_BAND_TYPE, 6400, 10800, 10390, 1, 0, 1, 0, 0, 0},
  152.     {"MW1", MW_BAND_TYPE, 150, 1720, 810, 3, 4, 0, 0, 0, 32},
  153.     {"MW2", MW_BAND_TYPE, 531, 1701, 783, 2, 4, 0, 0, 0, 32},
  154.     {"MW3", MW_BAND_TYPE, 1700, 3500, 2500, 1, 4, 1, 0, 0, 32},
  155.     {"80M", MW_BAND_TYPE, 3500, 4000, 3700, 0, 4, 1, 0, 0, 32},
  156.     {"SW1", SW_BAND_TYPE, 4000, 5500, 4885, 1, 4, 1, 0, 0, 32},
  157.     {"SW2", SW_BAND_TYPE, 5500, 6500, 6000, 1, 4, 1, 0, 0, 32},
  158.     {"40M", SW_BAND_TYPE, 6500, 7300, 7100, 0, 4, 1, 0, 0, 40},
  159.     {"SW3", SW_BAND_TYPE, 7200, 8000, 7200, 1, 4, 1, 0, 0, 40},
  160.     {"SW4", SW_BAND_TYPE, 9000, 11000, 9500, 1, 4, 1, 0, 0, 40},
  161.     {"SW5", SW_BAND_TYPE, 11100, 13000, 11900, 1, 4, 1, 0, 0, 40},
  162.     {"SW6", SW_BAND_TYPE, 13000, 14000, 13500, 1, 4, 1, 0, 0, 40},
  163.     {"20M", SW_BAND_TYPE, 14000, 15000, 14200, 0, 4, 1, 0, 0, 42},
  164.     {"SW7", SW_BAND_TYPE, 15000, 17000, 15300, 1, 4, 1, 0, 0, 42},
  165.     {"SW8", SW_BAND_TYPE, 17000, 18000, 17500, 1, 4, 1, 0, 0, 42},
  166.     {"15M", SW_BAND_TYPE, 20000, 21400, 21100, 0, 4, 1, 0, 0, 44},
  167.     {"SW9", SW_BAND_TYPE, 21400, 22800, 21500, 1, 4, 1, 0, 0, 44},
  168.     {"CB ", SW_BAND_TYPE, 26000, 28000, 27500, 0, 4, 1, 0, 0, 44},
  169.     {"10M", SW_BAND_TYPE, 28000, 30000, 28400, 0, 4, 1, 0, 0, 44},
  170.     {"ALL", SW_BAND_TYPE, 150, 30000, 15000, 0, 4, 1, 0, 0, 48} // All band. LW, MW and SW (from 150kHz to 30MHz)
  171. };

  172. const int lastBand = (sizeof band / sizeof(Band)) - 1;
  173. int bandIdx = 0;
  174. int tabStep[] = {1, 5, 10, 50, 100, 500, 1000};
  175. const int lastStep = (sizeof tabStep / sizeof(int)) - 1;


  176. uint8_t rssi = 0;
  177. uint8_t volume = DEFAULT_VOLUME;

  178. // Devices class declarations
  179. Rotary encoder = Rotary(ENCODER_PIN_A, ENCODER_PIN_B);

  180. LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
  181. SI4735 rx;


  182. void setup()
  183. {
  184.   // Encoder pins
  185.   pinMode(ENCODER_PUSH_BUTTON, INPUT_PULLUP);
  186.   pinMode(ENCODER_PIN_A, INPUT_PULLUP);
  187.   pinMode(ENCODER_PIN_B, INPUT_PULLUP);
  188.   lcd.begin(16, 2);



  189.   // Splash - Remove or Change the splash message
  190.   lcd.setCursor(3, 0);//显示器光标,原为0,0
  191.   lcd.print("SI4732A10");//打印("SI4732A10")原为“PU2CLR-SI4735”
  192.   lcd.setCursor(0, 1);
  193.   lcd.print("Arduino Library");
  194.   Flash(1500);
  195.   lcd.setCursor(0, 0);
  196.   lcd.print("DIY Mirko Radio");
  197.   lcd.setCursor(0, 1);
  198.   lcd.print("By RICARDO/2021");
  199.   Flash(2000);
  200.   // End splash

  201.   EEPROM.begin();

  202.   // If you want to reset the eeprom, keep the VOLUME_UP button pressed during statup
  203.   if (digitalRead(ENCODER_PUSH_BUTTON) == LOW)
  204.   {
  205.     EEPROM.update(eeprom_address, 0);
  206.     lcd.setCursor(0,0);
  207.     lcd.print("EEPROM RESETED");
  208.     delay(2000);
  209.     lcd.clear();
  210.   }

  211.   // controlling encoder via interrupt
  212.   attachInterrupt(digitalPinToInterrupt(ENCODER_PIN_A), rotaryEncoder, CHANGE);
  213.   attachInterrupt(digitalPinToInterrupt(ENCODER_PIN_B), rotaryEncoder, CHANGE);

  214.   rx.setI2CFastModeCustom(100000);
  215.   
  216.   rx.getDeviceI2CAddress(RESET_PIN); // Looks for the I2C bus address and set it.  Returns 0 if error
  217.   
  218.   rx.setup(RESET_PIN, MW_BAND_TYPE);
  219.   // Comment the line above and uncomment the three lines below if you are using external ref clock (active crystal or signal generator)
  220.   // rx.setRefClock(32768);
  221.   // rx.setRefClockPrescaler(1);   // will work with 32768  
  222.   // rx.setup(RESET_PIN, 0, MW_BAND_TYPE, SI473X_ANALOG_AUDIO, XOSCEN_RCLK);

  223.   
  224.   delay(300);
  225.   rx.setAvcAmMaxGain(48); // Sets the maximum gain for automatic volume control on AM/SSB mode (you can use values between 12 and 90dB).


  226.   // Checking the EEPROM content
  227.   if (EEPROM.read(eeprom_address) == app_id)
  228.   {
  229.     readAllReceiverInformation();
  230.   } else
  231.     rx.setVolume(volume);
  232.   
  233.   useBand();
  234.   showStatus();
  235. }

  236. /**
  237. *  Cleans the screen with a visual effect.
  238. */
  239. void Flash(int d)
  240. {
  241.   delay(d);
  242.   lcd.clear();
  243.   lcd.noDisplay();
  244.   delay(500);
  245.   lcd.display();
  246. }

  247. /*
  248.    writes the conrrent receiver information into the eeprom.
  249.    The EEPROM.update avoid write the same data in the same memory position. It will save unnecessary recording.
  250. */
  251. void saveAllReceiverInformation()
  252. {
  253.   int addr_offset;

  254.   EEPROM.begin();

  255.   EEPROM.update(eeprom_address, app_id);                 // stores the app id;
  256.   EEPROM.update(eeprom_address + 1, rx.getVolume()); // stores the current Volume
  257.   EEPROM.update(eeprom_address + 2, bandIdx);            // Stores the current band
  258.   EEPROM.update(eeprom_address + 3, fmRDS);
  259.   EEPROM.update(eeprom_address + 4, currentMode); // Stores the current Mode (FM / AM / SSB)
  260.   EEPROM.update(eeprom_address + 5, currentBFO >> 8);
  261.   EEPROM.update(eeprom_address + 6, currentBFO & 0XFF);

  262.   addr_offset = 7;
  263.   band[bandIdx].currentFreq = currentFrequency;

  264.   for (int i = 0; i <= lastBand; i++)
  265.   {
  266.     EEPROM.update(addr_offset++, (band[i].currentFreq >> 8));   // stores the current Frequency HIGH byte for the band
  267.     EEPROM.update(addr_offset++, (band[i].currentFreq & 0xFF)); // stores the current Frequency LOW byte for the band
  268.     EEPROM.update(addr_offset++, band[i].currentStepIdx);       // Stores current step of the band
  269.     EEPROM.update(addr_offset++, band[i].bandwidthIdx);         // table index (direct position) of bandwidth
  270.     EEPROM.update(addr_offset++, band[i].disableAgc );
  271.     EEPROM.update(addr_offset++, band[i].agcIdx);
  272.     EEPROM.update(addr_offset++, band[i].agcNdx);
  273.     EEPROM.update(addr_offset++, band[i].avcIdx);

  274.   }

  275.   EEPROM.end();
  276. }

  277. /**
  278. * reads the last receiver status from eeprom.
  279. */
  280. void readAllReceiverInformation()
  281. {
  282.   uint8_t volume;
  283.   int addr_offset;
  284.   int bwIdx;

  285.   volume = EEPROM.read(eeprom_address + 1); // Gets the stored volume;
  286.   bandIdx = EEPROM.read(eeprom_address + 2);
  287.   fmRDS = EEPROM.read(eeprom_address + 3);
  288.   currentMode = EEPROM.read(eeprom_address + 4);
  289.   currentBFO = EEPROM.read(eeprom_address + 5) << 8;
  290.   currentBFO |= EEPROM.read(eeprom_address + 6);

  291.   addr_offset = 7;
  292.   for (int i = 0; i <= lastBand; i++)
  293.   {
  294.     band[i].currentFreq = EEPROM.read(addr_offset++) << 8;
  295.     band[i].currentFreq |= EEPROM.read(addr_offset++);
  296.     band[i].currentStepIdx = EEPROM.read(addr_offset++);
  297.     band[i].bandwidthIdx = EEPROM.read(addr_offset++);
  298.     band[i].disableAgc = EEPROM.read(addr_offset++);
  299.     band[i].agcIdx = EEPROM.read(addr_offset++);
  300.     band[i].agcNdx = EEPROM.read(addr_offset++);
  301.     band[i].avcIdx = EEPROM.read(addr_offset++);
  302.   }


  303.   currentFrequency = band[bandIdx].currentFreq;

  304.   if (band[bandIdx].bandType == FM_BAND_TYPE)
  305.   {
  306.     currentStepIdx = idxFmStep = band[bandIdx].currentStepIdx;
  307.     rx.setFrequencyStep(tabFmStep[currentStepIdx]);
  308.   }
  309.   else
  310.   {
  311.     currentStepIdx = idxAmStep = band[bandIdx].currentStepIdx;
  312.     rx.setFrequencyStep(tabAmStep[currentStepIdx]);
  313.   }

  314.   bwIdx = band[bandIdx].bandwidthIdx;

  315.   if (currentMode == LSB || currentMode == USB)
  316.   {
  317.     loadSSB();
  318.     bwIdxSSB = (bwIdx > 5) ? 5 : bwIdx;
  319.     rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  320.     // If audio bandwidth selected is about 2 kHz or below, it is recommended to set Sideband Cutoff Filter to 0.
  321.     if (bandwidthSSB[bwIdxSSB].idx == 0 || bandwidthSSB[bwIdxSSB].idx == 4 || bandwidthSSB[bwIdxSSB].idx == 5)
  322.       rx.setSBBSidebandCutoffFilter(0);
  323.     else
  324.       rx.setSBBSidebandCutoffFilter(1);
  325.   }
  326.   else if (currentMode == AM)
  327.   {
  328.     bwIdxAM = bwIdx;
  329.     rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  330.   }
  331.   else
  332.   {
  333.     bwIdxFM = bwIdx;
  334.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);
  335.   }

  336.   delay(50);
  337.   rx.setVolume(volume);
  338. }

  339. /*
  340. * To store any change into the EEPROM, it is needed at least STORE_TIME  milliseconds of inactivity.
  341. */
  342. void resetEepromDelay()
  343. {
  344.   elapsedCommand = storeTime = millis();
  345.   itIsTimeToSave = true;
  346. }

  347. /**
  348.     Set all command flags to false
  349.     When all flags are disabled (false), the encoder controls the frequency
  350. */
  351. void disableCommands()
  352. {
  353.   cmdBand = false;
  354.   bfoOn = false;
  355.   cmdVolume = false;
  356.   cmdAgc = false;
  357.   cmdBandwidth = false;
  358.   cmdStep = false;
  359.   cmdMode = false;
  360.   cmdMenu = false;
  361.   cmdSoftMuteMaxAtt = false;
  362.   cmdRds = false;
  363.   cmdAvc =  false;
  364.   countClick = 0;

  365.   showCommandStatus((char *) "VFO ");
  366. }



  367. /**
  368. * Reads encoder via interrupt
  369. * Use Rotary.h and  Rotary.cpp implementation to process encoder via interrupt
  370. * if you do not add ICACHE_RAM_ATTR declaration, the system will reboot during attachInterrupt call.
  371. * With ICACHE_RAM_ATTR macro you put the function on the RAM.
  372. */
  373. void  rotaryEncoder()
  374. { // rotary encoder events
  375.   uint8_t encoderStatus = encoder.process();
  376.   if (encoderStatus)
  377.     encoderCount = (encoderStatus == DIR_CW) ? 1 : -1;
  378. }

  379. /**
  380. * Shows frequency information on Display
  381. */
  382. void showFrequency()
  383. {
  384.   char tmp[15];
  385.   char bufferDisplay[15];
  386.   char *unit;
  387.   int col = 4;
  388.   sprintf(tmp, "%5.5u", currentFrequency);
  389.   bufferDisplay[0] = (tmp[0] == '0') ? ' ' : tmp[0];
  390.   bufferDisplay[1] = tmp[1];
  391.   if (rx.isCurrentTuneFM())
  392.   {
  393.     bufferDisplay[2] = tmp[2];
  394.     bufferDisplay[3] = '.';
  395.     bufferDisplay[4] = tmp[3];
  396.     if ( fmRDS ) {
  397.       col = 0;
  398.       unit = (char *)" ";
  399.     } else {
  400.       unit = (char *)"MHz";
  401.     }
  402.   }
  403.   else
  404.   {
  405.     if (currentFrequency < 1000)
  406.     {
  407.       bufferDisplay[1] = ' ';
  408.       bufferDisplay[2] = tmp[2];
  409.       bufferDisplay[3] = tmp[3];
  410.       bufferDisplay[4] = tmp[4];
  411.     }
  412.     else
  413.     {
  414.       bufferDisplay[2] = tmp[2];
  415.       bufferDisplay[3] = tmp[3];
  416.       bufferDisplay[4] = tmp[4];
  417.     }
  418.     unit = (char *)"kHz";
  419.   }
  420.   bufferDisplay[5] = '\0';
  421.   strcat(bufferDisplay, unit);
  422.   lcd.setCursor(col, 1);
  423.   lcd.print(bufferDisplay);
  424.   showMode();
  425. }

  426. /**
  427. * Shows the current mode
  428. */
  429. void showMode()
  430. {
  431.   char *bandMode;

  432.    
  433.   if (currentFrequency < 520)
  434.     bandMode = (char *)"LW  ";
  435.   else
  436.     bandMode = (char *)bandModeDesc[currentMode];
  437.   lcd.setCursor(0, 0);
  438.   lcd.print(bandMode);

  439.   if ( currentMode == FM && fmRDS ) return;
  440.   
  441.   lcd.setCursor(0, 1);
  442.   lcd.print(band[bandIdx].bandName);
  443. }

  444. /**
  445. * Shows some basic information on display
  446. */
  447. void showStatus()
  448. {
  449.   lcd.clear();
  450.   showFrequency();
  451.   showRSSI();
  452. }

  453. /**
  454. *  Shows the current Bandwidth status
  455. */
  456. void showBandwidth()
  457. {
  458.   char *bw;
  459.   char bandwidth[20];
  460.   if (currentMode == LSB || currentMode == USB)
  461.   {
  462.     bw = (char *)bandwidthSSB[bwIdxSSB].desc;
  463.     showBFO();
  464.   }
  465.   else if (currentMode == AM)
  466.   {
  467.     bw = (char *)bandwidthAM[bwIdxAM].desc;
  468.   }
  469.   else
  470.   {
  471.     bw = (char *)bandwidthFM[bwIdxFM].desc;
  472.   }

  473.   sprintf(bandwidth, "BW: %s", bw);
  474.   lcd.clear();
  475.   lcd.setCursor(0, 0);
  476.   lcd.print(bandwidth);
  477. }

  478. /**
  479. *   Shows the current RSSI and SNR status
  480. */
  481. void showRSSI()
  482. {
  483.   int rssiAux = 0;
  484.   char sMeter[7];

  485.   if (currentMode == FM)
  486.   {
  487.     lcd.setCursor(14, 0);
  488.     lcd.print((rx.getCurrentPilot()) ? "ST" : "MO");
  489.     lcd.setCursor(10, 0);
  490.     if ( fmRDS ) {
  491.       lcd.print("RDS");
  492.       return;
  493.     }
  494.     else
  495.       lcd.print("   ");
  496.   }

  497.    
  498.   if (rssi < 2)
  499.     rssiAux = 4;
  500.   else if (rssi < 4)
  501.     rssiAux = 5;
  502.   else if (rssi < 12)
  503.     rssiAux = 6;
  504.   else if (rssi < 25)
  505.     rssiAux = 7;
  506.   else if (rssi < 50)
  507.     rssiAux = 8;
  508.   else
  509.     rssiAux = 9;

  510.   sprintf(sMeter, "S%1.1u%c", rssiAux, (rssi >= 60) ? '+' : '.');
  511.   lcd.setCursor(13, 1);
  512.   lcd.print(sMeter);
  513. }

  514. /**
  515. *    Shows the current AGC and Attenuation status
  516. */
  517. void showAgcAtt()
  518. {
  519.   char sAgc[15];
  520.   lcd.clear();
  521.   rx.getAutomaticGainControl();
  522.   if ( !disableAgc /*agcNdx == 0 && agcIdx == 0 */ )
  523.     strcpy(sAgc, "AGC ON");
  524.   else
  525.     sprintf(sAgc, "ATT: %2.2d", agcNdx);

  526.   lcd.setCursor(0, 0);
  527.   lcd.print(sAgc);
  528. }


  529. /**
  530. *   Shows the current step
  531. */
  532. void showStep()
  533. {
  534.   char sStep[15];

  535.   sprintf(sStep, "Stp:%4d", (currentMode == FM)? (tabFmStep[currentStepIdx] *10) : tabAmStep[currentStepIdx] );
  536.   lcd.setCursor(0, 0);
  537.   lcd.print(sStep);
  538. }

  539. /**
  540. *  Shows the current BFO value
  541. */
  542. void showBFO()
  543. {
  544.   char bfo[15];
  545.   if (currentBFO > 0)
  546.     sprintf(bfo, "BFO:+%4.4d", currentBFO);
  547.   else
  548.     sprintf(bfo, "BFO:%4.4d", currentBFO);

  549.   lcd.clear();
  550.   lcd.setCursor(0, 0);
  551.   lcd.print(bfo);
  552.   elapsedCommand = millis();
  553. }

  554. /*
  555. *  Shows the volume level on LCD
  556. */
  557. void showVolume()
  558. {
  559.   char volAux[12];
  560.   sprintf(volAux, "VOLUME: %2u", rx.getVolume());
  561.   lcd.clear();
  562.   lcd.setCursor(0, 0);
  563.   lcd.print(volAux);
  564. }

  565. /**
  566. * Show Soft Mute
  567. */
  568. void showSoftMute()
  569. {
  570.   char sMute[18];
  571.   sprintf(sMute, "Soft Mute: %2d", softMuteMaxAttIdx);
  572.   lcd.clear();
  573.   lcd.setCursor(0, 0);
  574.   lcd.print(sMute);
  575. }


  576. /**
  577. * Show Soft Mute
  578. */
  579. void showAvc()
  580. {
  581.   char sAvc[18];
  582.   sprintf(sAvc, "AVC: %2d", avcIdx);
  583.   lcd.clear();
  584.   lcd.setCursor(0, 0);
  585.   lcd.print(sAvc);
  586. }



  587. /**
  588. * Shows RDS ON or OFF
  589. */
  590. void showRdsSetup()
  591. {
  592.   char sRdsStatus[10];
  593.   sprintf(sRdsStatus, "RDS: %s", (fmRDS)? "ON ": "OFF");
  594.   lcd.clear();
  595.   lcd.setCursor(0, 0);
  596.   lcd.print(sRdsStatus);  

  597. }

  598. /***************  
  599. *   RDS
  600. *   
  601. */

  602. char *stationName;
  603. char bufferStatioName[20];

  604. void clearRDS() {
  605.    stationName = (char *) "           ";
  606.    showRDSStation();
  607. }

  608. void showRDSStation()
  609. {
  610.     int col = 8;
  611.     for (int i = 0; i < 8; i++ ) {
  612.       if (stationName[i] != bufferStatioName[i] ) {
  613.         lcd.setCursor(col + i, 1);
  614.         lcd.print(stationName[i]);
  615.         bufferStatioName[i] = stationName[i];
  616.       }
  617.     }
  618.    
  619.     delay(100);
  620. }


  621. /*
  622. * Checks the station name is available
  623. */
  624. void checkRDS()
  625. {
  626.   rx.getRdsStatus();
  627.   if (rx.getRdsReceived())
  628.   {
  629.     if (rx.getRdsSync() && rx.getRdsSyncFound() && !rx.getRdsSyncLost() && !rx.getGroupLost() )
  630.     {
  631.       stationName = rx.getRdsText0A();
  632.       if (stationName != NULL )
  633.       {
  634.         showRDSStation();
  635.       }
  636.     }
  637.   }
  638. }


  639. /**
  640. *   Sets Band up (1) or down (!1)
  641. */
  642. void setBand(int8_t up_down)
  643. {
  644.   band[bandIdx].currentFreq = currentFrequency;
  645.   band[bandIdx].currentStepIdx = currentStepIdx;
  646.   if (up_down == 1)
  647.     bandIdx = (bandIdx < lastBand) ? (bandIdx + 1) : 0;
  648.   else
  649.     bandIdx = (bandIdx > 0) ? (bandIdx - 1) : lastBand;
  650.   useBand();
  651.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  652. }

  653. /**
  654. * Switch the radio to current band
  655. */
  656. void useBand()
  657. {
  658.   if (band[bandIdx].bandType == FM_BAND_TYPE)
  659.   {
  660.     currentMode = FM;
  661.     rx.setTuneFrequencyAntennaCapacitor(0);
  662.     rx.setFM(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabFmStep[band[bandIdx].currentStepIdx]);
  663.     rx.setSeekFmLimits(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq);
  664.     rx.setRdsConfig(1, 2, 2, 2, 2);
  665.     rx.setFifoCount(1);
  666.    
  667.     bfoOn = ssbLoaded = false;
  668.     bwIdxFM = band[bandIdx].bandwidthIdx;
  669.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);   
  670.   }
  671.   else
  672.   {

  673.     disableAgc = band[bandIdx].disableAgc;
  674.     agcIdx = band[bandIdx].agcIdx;
  675.     agcNdx = band[bandIdx].agcNdx;
  676.     avcIdx = band[bandIdx].avcIdx;
  677.    
  678.     // set the tuning capacitor for SW or MW/LW
  679.     rx.setTuneFrequencyAntennaCapacitor((band[bandIdx].bandType == MW_BAND_TYPE || band[bandIdx].bandType == LW_BAND_TYPE) ? 0 : 1);
  680.     if (ssbLoaded)
  681.     {
  682.       rx.setSSB(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabAmStep[band[bandIdx].currentStepIdx], currentMode);
  683.       rx.setSSBAutomaticVolumeControl(1);
  684.       rx.setSsbSoftMuteMaxAttenuation(softMuteMaxAttIdx); // Disable Soft Mute for SSB
  685.       bwIdxSSB = band[bandIdx].bandwidthIdx;
  686.       rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  687.       delay(500);
  688.       rx.setSsbAgcOverrite(disableAgc, agcNdx);
  689.     }
  690.     else
  691.     {
  692.       currentMode = AM;
  693.       rx.setAM(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabAmStep[band[bandIdx].currentStepIdx]);
  694.       bfoOn = false;
  695.       bwIdxAM = band[bandIdx].bandwidthIdx;
  696.       rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  697.       rx.setAmSoftMuteMaxAttenuation(softMuteMaxAttIdx); // Soft Mute for AM or SSB
  698.       rx.setAutomaticGainControl(disableAgc, agcNdx);

  699.     }
  700.     rx.setSeekAmLimits(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq); // Consider the range all defined current band
  701.     rx.setSeekAmSpacing(5); // Max 10kHz for spacing
  702.     rx.setAvcAmMaxGain(avcIdx);
  703.   }
  704.   delay(100);
  705.   currentFrequency = band[bandIdx].currentFreq;
  706.   currentStepIdx = band[bandIdx].currentStepIdx;

  707.   rssi = 0;
  708.   showStatus();
  709.   showCommandStatus((char *) "Band");
  710. }


  711. void loadSSB() {
  712.    rx.setI2CFastModeCustom(400000); // You can try rx.setI2CFastModeCustom(700000); or greater value
  713.    rx.loadPatch(ssb_patch_content, size_content, bandwidthSSB[bwIdxSSB].idx);
  714.    rx.setI2CFastModeCustom(100000);  
  715.    ssbLoaded =  true;
  716. }

  717. /**
  718. *  Switches the Bandwidth
  719. */
  720. void doBandwidth(int8_t v)
  721. {
  722.     if (currentMode == LSB || currentMode == USB)
  723.     {
  724.       bwIdxSSB = (v == 1) ? bwIdxSSB + 1 : bwIdxSSB - 1;

  725.       if (bwIdxSSB > maxSsbBw)
  726.         bwIdxSSB = 0;
  727.       else if (bwIdxSSB < 0)
  728.         bwIdxSSB = maxSsbBw;

  729.       rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  730.       // If audio bandwidth selected is about 2 kHz or below, it is recommended to set Sideband Cutoff Filter to 0.
  731.       if (bandwidthSSB[bwIdxSSB].idx == 0 || bandwidthSSB[bwIdxSSB].idx == 4 || bandwidthSSB[bwIdxSSB].idx == 5)
  732.         rx.setSBBSidebandCutoffFilter(0);
  733.       else
  734.         rx.setSBBSidebandCutoffFilter(1);

  735.       band[bandIdx].bandwidthIdx = bwIdxSSB;
  736.     }
  737.     else if (currentMode == AM)
  738.     {
  739.       bwIdxAM = (v == 1) ? bwIdxAM + 1 : bwIdxAM - 1;

  740.       if (bwIdxAM > maxAmBw)
  741.         bwIdxAM = 0;
  742.       else if (bwIdxAM < 0)
  743.         bwIdxAM = maxAmBw;

  744.       rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  745.       band[bandIdx].bandwidthIdx = bwIdxAM;
  746.       
  747.     } else {
  748.     bwIdxFM = (v == 1) ? bwIdxFM + 1 : bwIdxFM - 1;
  749.     if (bwIdxFM > maxFmBw)
  750.       bwIdxFM = 0;
  751.     else if (bwIdxFM < 0)
  752.       bwIdxFM = maxFmBw;

  753.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);
  754.     band[bandIdx].bandwidthIdx = bwIdxFM;
  755.   }
  756.   showBandwidth();
  757.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  758. }

  759. /**
  760. * Show cmd on display. It means you are setting up something.  
  761. */
  762. void showCommandStatus(char * currentCmd)
  763. {
  764.   lcd.setCursor(5, 0);
  765.   lcd.print(currentCmd);
  766. }

  767. /**
  768. * Show menu options
  769. */
  770. void showMenu() {
  771.   lcd.clear();
  772.   lcd.setCursor(0, 0);
  773.   lcd.setCursor(0, 1);
  774.   lcd.print(menu[menuIdx]);
  775.   showCommandStatus( (char *) "Menu");
  776. }

  777. /**
  778. *  AGC and attenuattion setup
  779. */
  780. void doAgc(int8_t v) {
  781.   agcIdx = (v == 1) ? agcIdx + 1 : agcIdx - 1;
  782.   if (agcIdx < 0 )
  783.     agcIdx = 37;
  784.   else if ( agcIdx > 37)
  785.     agcIdx = 0;
  786.   disableAgc = (agcIdx > 0); // if true, disable AGC; esle, AGC is enable
  787.   if (agcIdx > 1)
  788.     agcNdx = agcIdx - 1;
  789.   else
  790.     agcNdx = 0;
  791.   if ( currentMode == AM )
  792.      rx.setAutomaticGainControl(disableAgc, agcNdx); // if agcNdx = 0, no attenuation
  793.   else
  794.     rx.setSsbAgcOverrite(disableAgc, agcNdx, 0B1111111);

  795.   band[bandIdx].disableAgc = disableAgc;
  796.   band[bandIdx].agcIdx = agcIdx;
  797.   band[bandIdx].agcNdx = agcNdx;

  798.   showAgcAtt();
  799.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  800.   elapsedCommand = millis();
  801. }


  802. /**
  803. * Switches the current step
  804. */
  805. void doStep(int8_t v)
  806. {
  807.     if ( currentMode == FM ) {
  808.       idxFmStep = (v == 1) ? idxFmStep + 1 : idxFmStep - 1;
  809.       if (idxFmStep > lastFmStep)
  810.         idxFmStep = 0;
  811.       else if (idxFmStep < 0)
  812.         idxFmStep = lastFmStep;
  813.         
  814.       currentStepIdx = idxFmStep;
  815.       rx.setFrequencyStep(tabFmStep[currentStepIdx]);
  816.       
  817.     } else {
  818.       idxAmStep = (v == 1) ? idxAmStep + 1 : idxAmStep - 1;
  819.       if (idxAmStep > lastAmStep)
  820.         idxAmStep = 0;
  821.       else if (idxAmStep < 0)
  822.         idxAmStep = lastAmStep;

  823.       currentStepIdx = idxAmStep;
  824.       rx.setFrequencyStep(tabAmStep[currentStepIdx]);
  825.       rx.setSeekAmSpacing(5); // Max 10kHz for spacing
  826.     }
  827.     band[bandIdx].currentStepIdx = currentStepIdx;
  828.     showStep();
  829.     delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  830.     elapsedCommand = millis();
  831. }

  832. /**
  833. * Switches to the AM, LSB or USB modes
  834. */
  835. void doMode(int8_t v)
  836. {
  837.   if (currentMode != FM)
  838.   {
  839.     if (v == 1)  { // clockwise
  840.       if (currentMode == AM)
  841.       {
  842.         // If you were in AM mode, it is necessary to load SSB patch (avery time)
  843.         loadSSB();
  844.         ssbLoaded = true;
  845.         currentMode = LSB;
  846.       }
  847.       else if (currentMode == LSB)
  848.         currentMode = USB;
  849.       else if (currentMode == USB)
  850.       {
  851.         currentMode = AM;
  852.         bfoOn = ssbLoaded = false;
  853.       }
  854.     } else { // and counterclockwise
  855.       if (currentMode == AM)
  856.       {
  857.         // If you were in AM mode, it is necessary to load SSB patch (avery time)
  858.         loadSSB();
  859.         ssbLoaded = true;
  860.         currentMode = USB;
  861.       }
  862.       else if (currentMode == USB)
  863.         currentMode = LSB;
  864.       else if (currentMode == LSB)
  865.       {
  866.         currentMode = AM;
  867.         bfoOn = ssbLoaded = false;
  868.       }
  869.     }
  870.     // Nothing to do if you are in FM mode
  871.     band[bandIdx].currentFreq = currentFrequency;
  872.     band[bandIdx].currentStepIdx = currentStepIdx;
  873.     useBand();
  874.   }
  875.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  876.   elapsedCommand = millis();
  877. }

  878. /**
  879. * Sets the audio volume
  880. */
  881. void doVolume( int8_t v ) {
  882.   if ( v == 1)
  883.     rx.volumeUp();
  884.   else
  885.     rx.volumeDown();

  886.   showVolume();
  887.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  888. }

  889. /**
  890. *  This function is called by the seek function process.
  891. */
  892. void showFrequencySeek(uint16_t freq)
  893. {
  894.   currentFrequency = freq;
  895.   showFrequency();
  896. }

  897. /**
  898. *  Find a station. The direction is based on the last encoder move clockwise or counterclockwise
  899. */
  900. void doSeek()
  901. {
  902.   if ((currentMode == LSB || currentMode == USB)) return; // It does not work for SSB mode

  903.   lcd.clear();
  904.   rx.seekStationProgress(showFrequencySeek, seekDirection);
  905.   showStatus();
  906.   currentFrequency = rx.getFrequency();
  907.   
  908. }

  909. /**
  910. * Sets the Soft Mute Parameter
  911. */
  912. void doSoftMute(int8_t v)
  913. {
  914.   softMuteMaxAttIdx = (v == 1) ? softMuteMaxAttIdx + 1 : softMuteMaxAttIdx - 1;
  915.   if (softMuteMaxAttIdx > 32)
  916.     softMuteMaxAttIdx = 0;
  917.   else if (softMuteMaxAttIdx < 0)
  918.     softMuteMaxAttIdx = 32;

  919.   rx.setAmSoftMuteMaxAttenuation(softMuteMaxAttIdx);
  920.   showSoftMute();
  921.   elapsedCommand = millis();
  922. }


  923. /**
  924. * Sets the Max gain for Automatic Volume Control.
  925. */
  926. void doAvc(int8_t v)
  927. {
  928.   avcIdx = (v == 1) ? avcIdx + 2 : avcIdx - 2;
  929.   if (avcIdx > 90)
  930.     avcIdx = 12;
  931.   else if (avcIdx < 12)
  932.     avcIdx = 90;

  933.   rx.setAvcAmMaxGain(avcIdx);

  934.   band[bandIdx].avcIdx = avcIdx;

  935.   showAvc();
  936.   elapsedCommand = millis();
  937. }


  938. /**
  939. * Turns RDS ON or OFF
  940. */
  941. void doRdsSetup(int8_t v)
  942. {
  943.   fmRDS = (v == 1)? true:false;
  944.   showRdsSetup();
  945.   elapsedCommand = millis();
  946. }


  947. /**
  948. *  Menu options selection
  949. */
  950. void doMenu( int8_t v) {
  951.   menuIdx = (v == 1) ? menuIdx + 1 : menuIdx - 1;
  952.   if (menuIdx > lastMenu)
  953.     menuIdx = 0;
  954.   else if (menuIdx < 0)
  955.     menuIdx = lastMenu;

  956.   showMenu();
  957.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  958.   elapsedCommand = millis();
  959. }



  960. /**
  961. * Return true if the current status is Menu command
  962. */
  963. bool isMenuMode() {
  964.   return (cmdMenu | cmdStep | cmdBandwidth | cmdAgc | cmdVolume | cmdSoftMuteMaxAtt | cmdMode | cmdRds | cmdAvc);
  965. }


  966. /**
  967. * Starts the MENU action process
  968. */
  969. void doCurrentMenuCmd() {
  970.   disableCommands();
  971.   switch (currentMenuCmd) {
  972.      case 0:                 // VOLUME
  973.       cmdVolume = true;
  974.       showVolume();
  975.       break;
  976.     case 1:
  977.       cmdRds = true;
  978.       showRdsSetup();
  979.       break;
  980.     case 2:                 // STEP
  981.       cmdStep = true;
  982.       showStep();
  983.       break;
  984.     case 3:                 // MODE
  985.       cmdMode = true;
  986.       lcd.clear();
  987.       showMode();
  988.       break;
  989.     case 4:
  990.         bfoOn = true;
  991.         if ((currentMode == LSB || currentMode == USB)) {
  992.           showBFO();
  993.         }
  994.       // showFrequency();
  995.       break;      
  996.     case 5:                 // BW
  997.       cmdBandwidth = true;
  998.       showBandwidth();
  999.       break;
  1000.     case 6:                 // AGC/ATT
  1001.       cmdAgc = true;
  1002.       showAgcAtt();
  1003.       break;
  1004.     case 7:
  1005.       cmdSoftMuteMaxAtt = true;
  1006.       showSoftMute();  
  1007.       break;
  1008.     case 8:
  1009.       cmdAvc =  true;
  1010.       showAvc();
  1011.       break;  
  1012.     case 9:
  1013.       seekDirection = 1;
  1014.       doSeek();
  1015.       break;  
  1016.     case 10:
  1017.       seekDirection = 0;
  1018.       doSeek();
  1019.       break;   
  1020.     default:
  1021.       showStatus();
  1022.       break;
  1023.   }
  1024.   currentMenuCmd = -1;
  1025.   elapsedCommand = millis();
  1026. }



  1027. /**
  1028. * Main loop
  1029. */
  1030. void loop()
  1031. {
  1032.   // 检查编码器是否移动.
  1033.   if (encoderCount != 0)
  1034.   {
  1035.     if (bfoOn & (currentMode == LSB || currentMode == USB))
  1036.     {
  1037.       currentBFO = (encoderCount == 1) ? (currentBFO + currentBFOStep) : (currentBFO - currentBFOStep);
  1038.       rx.setSSBBfo(currentBFO);
  1039.       showBFO();

  1040.   
  1041.       
  1042.     }


  1043.   
  1044.     else if (cmdMenu)
  1045.       doMenu(encoderCount);
  1046.     else if (cmdMode)
  1047.       doMode(encoderCount);
  1048.     else if (cmdStep)
  1049.       doStep(encoderCount);
  1050.     else if (cmdAgc)
  1051.       doAgc(encoderCount);
  1052.     else if (cmdBandwidth)
  1053.       doBandwidth(encoderCount);
  1054.     else if (cmdVolume)
  1055.       doVolume(encoderCount);
  1056.     else if (cmdSoftMuteMaxAtt)
  1057.       doSoftMute(encoderCount);
  1058.     else if (cmdAvc)
  1059.       doAvc(encoderCount);      
  1060.     else if (cmdBand)
  1061.       setBand(encoderCount);
  1062.     else if (cmdRds )
  1063.       doRdsSetup(encoderCount);  
  1064.     else
  1065.     {
  1066.       if (encoderCount == 1)
  1067.       {
  1068.      
  1069.         rx.frequencyUp();
  1070.       }
  1071.       else
  1072.       {
  1073.         rx.frequencyDown();
  1074.       }
  1075.       // Show the current frequency only if it has changed
  1076.       currentFrequency = rx.getFrequency();
  1077.       showFrequency();
  1078.     }
  1079.     encoderCount = 0;
  1080.     resetEepromDelay();
  1081.   }
  1082.   else
  1083.   {
  1084.     if (digitalRead(ENCODER_PUSH_BUTTON) == LOW)
  1085.     {





  1086.       
  1087.       countClick++;
  1088.       if (cmdMenu)
  1089.       {
  1090.         currentMenuCmd = menuIdx;
  1091.         doCurrentMenuCmd();
  1092.       }
  1093.       else if (countClick == 1)
  1094.       { // If just one click, you can select the band by rotating the encoder
  1095.         if (isMenuMode())
  1096.         {
  1097.           disableCommands();
  1098.           showStatus();
  1099.           showCommandStatus((char *)"VFO ");
  1100.         }
  1101.         else if ( bfoOn ) {
  1102.           bfoOn = false;
  1103.           showStatus();
  1104.         }
  1105.         else
  1106.         {
  1107.           cmdBand = !cmdBand;
  1108.           showCommandStatus((char *)"Band");
  1109.         }
  1110.       }
  1111.       else
  1112.       { // GO to MENU if more than one click in less than 1/2 seconds.
  1113.         cmdMenu = !cmdMenu;
  1114.         if (cmdMenu)
  1115.           showMenu();
  1116.       }
  1117.       delay(MIN_ELAPSED_TIME);
  1118.       elapsedCommand = millis();
  1119.     }
  1120.   }

  1121.   // Show RSSI status only if this condition has changed
  1122.   if ((millis() - elapsedRSSI) > MIN_ELAPSED_RSSI_TIME * 6)
  1123.   {
  1124.     rx.getCurrentReceivedSignalQuality();
  1125.     int aux = rx.getCurrentRSSI();
  1126.     if (rssi != aux && !isMenuMode())
  1127.     {
  1128.       rssi = aux;
  1129.       showRSSI();
  1130.     }
  1131.     elapsedRSSI = millis();
  1132.   }

  1133.   // Disable commands control
  1134.   if ((millis() - elapsedCommand) > ELAPSED_COMMAND)
  1135.   {
  1136.     if ((currentMode == LSB || currentMode == USB) )
  1137.     {
  1138.       bfoOn = false;
  1139.       // showBFO();
  1140.       showStatus();
  1141.     } else if (isMenuMode())
  1142.       showStatus();
  1143.     disableCommands();
  1144.     elapsedCommand = millis();
  1145.   }

  1146.   if ((millis() - elapsedClick) > ELAPSED_CLICK)
  1147.   {
  1148.     countClick = 0;
  1149.     elapsedClick = millis();
  1150.   }

  1151.   // Show the current frequency only if it has changed
  1152.   if (itIsTimeToSave)
  1153.   {
  1154.     if ((millis() - storeTime) > STORE_TIME)
  1155.     {
  1156.       saveAllReceiverInformation();
  1157.       storeTime = millis();
  1158.       itIsTimeToSave = false;
  1159.     }
  1160.   }

  1161.   if (currentMode == FM && fmRDS && !isMenuMode() )
  1162.   {
  1163.       if (currentFrequency != previousFrequency)
  1164.       {
  1165.         clearRDS();
  1166.         previousFrequency = currentFrequency;
  1167.        }
  1168.       else
  1169.       {
  1170.         checkRDS();
  1171.       }
  1172.   }  

  1173.   delay(2);



  1174.   
  1175. }
复制代码
发表于 2022-3-16 06:56 | 显示全部楼层

由于你没有直接对我回复所以今天才看到程序,我看了几个Rotary.h库的示例没要求一定要占用2,3脚,你可以换出一个来用于中断;只要编码器旋转就会产生中断,中断程序中写上 digitalWrite(8,HIGH); 和
ptime= millis();语句,在主程序中添加;if(millis()-ptime>N) digitalWrite(8,LOW);就可实现你的要求。
发表于 2022-3-16 15:44 | 显示全部楼层

说具体点,比如将#define ENCODER_PIN_A 2改成#define ENCODER_PIN_A 10,连接10与2,在void setup()中添加attachInterrupt(0, abc, FALLING );。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 11:40 , Processed in 0.093876 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表