ããã€ãã®çç±ãããææ¡ããããªãã·ã§ã³ã¯ç§ã«åããªãã£ãã ãã®èšäºã§ã¯ãèªç©ºæ©ã¢ãã«çšã®ç¹æ» ããã³éç¹æ» LEDã³ã³ãããŒã©ãŒã®ããŒãžã§ã³ã«ã€ããŠèª¬æããŸããã
ã³ã³ãããŒã©ãŒã¯ATTiny13Aã«åºã¥ããŠããŸãã ãã®èšäºã¯ãAVRãã€ã¯ãã³ã³ãããŒã©ãŒãæ±ã人ã«ã圹ç«ã¡ãŸãã ç§ã¯ãã¹ãŠãåãã§æ£ã«çœ®ããŠã¿ãã®ã§ããã®èšäºã¯äž»ã«åå¿è ã«èå³ããããŸãã
ãã®ãããªããéçã®èœåãæšå®ã§ããŸãã
ãšã³ããªãŒ
ç§ããã®è³ªåãéžã³å§ãããã®èšäºã§ææ¡ãããããŒããã¯ãã ä»ããããããšããããã¯ç§ãå¿ èŠãšãããã®ã§ã¯ãªãããšãå€æããŸããã ãŸããé çªã«ã®ã¿ç¹æ» ã§ãããã£ãã«ã¯2ã€ãããããŸããã ã¿ã€ãã³ã°ã調æŽã§ããŸãããã¢ã«ãŽãªãºã ã¯ãã¡ãŒã ãŠã§ã¢ã«çµã¿èŸŒãŸããŠããŸãã 第äºã«ãããŒãäžã«ã¯ã°ã©ã ãè¿œå ãã3ã€ã®ãã¿ã³ãæ¢ã«ãããŸãã ãã©ã€ãããšã«ãŠã£ã³ã«ãŒãã¢ãã«ããšã«åé 眮ããããLEDãåããã°ã©ã ãããããããšã¯ãããŸãããã€ãŸãããããã®ãã¿ã³ã¯äžèŠã§ãã ã¯ã€ã€ãŒãã³ã³ãããŒã©ãŒã«çŽæ¥ã¯ãã ä»ãããå¿ èŠãªã¢ã«ãŽãªãºã ãããã°ã©ã ããããšã«äžåºŠåæããŸãã æåŸã«ã3çªç®ã«ããã¡ãŒã ãŠã§ã¢ã¯ãœãŒã¹ã³ãŒããªãã®ãã€ããªåœ¢åŒã§ãããããŸãããã€ãŸããäœãå€æŽããããšã¯äžå¯èœã§ãã
次ã®ã¢ãã«ãèããŠãç§ã¯ããã«å¿ èŠãªLEDã®æ°ãšããããç¹æ» ããæ¹æ³ãèŠã€ããŸããã ãåœå¢èª¿æ»ãã®çµæã4ã€ã®ãã£ãã«ãå¿ èŠã§ããããšãããããŸããïŒåãã£ãã«ã«ã¯2ã3åã®LEDããããŸããïŒã
- BANOïŒç©ºborneèªç©ºæ©ããã²ãŒã·ã§ã³ã©ã€ã-ç¿Œã®ç«¯ã«ããç·ãšèµ€ã®ã©ã€ãïŒ-ãããã¯åžžã«ç¹ç¯ããŠããŸã
- çéžç¯-ãªã¢ã³ã³ã®ãªã³/ãªããã€ãŸã åè·¯ã¯åä¿¡æ©ããã®PWMä¿¡å·ã«å¿çããå¿ èŠããããŸã
- ã²ãŒã-æã çãç¹æ» ããçœè²å ãšæã ç¹æ» ããçœè²å
- ç¹æ» ããŒã³ã³-å転ããå€ãåŠæ ¡ã®ãã¥ãŒãç¹æ» ããŒã³ã³ã«äŒŒããã¹ã ãŒãºã«ãªã³/ãªãããèµ€ãã©ã€ãã
ã¢ãã«ã¯å€§ãããé£ã¶ã ãããŠãããã¯LEDãèŠããã¹ãã§ããã匷åã§ãªããã°ãªããªãããšãæå³ããŸãã åã®ã¢ãã«ã§ã¯ãç§ã¯ã·ã³ã°ã«ã¯ããLEDã§BANOãè¡ããŸãã-æããæŽãã
匷åãªLEDã«é»åãäŸçµŠããããšã¯ããã»ã©ç°¡åã§ã¯ãªãããšãããããŸããã ããŒãã«ã¯ããªãã¢ã¹ã¿ãã©ã€ã¶ãŒïŒã¢ãŒã¿ãŒã³ã³ãããŒã©ãŒããŒãäžïŒããã®é»åãããããŸããã ã€ãŸãã1ã€ã®åŒ·åãªLEDã§ãïŒãã¡ããæµæãä»ããŠïŒæ¥ç¶ãããšãéåžžã«å€§ããªç±æ倱ãçºçããŸãã éåžžã«å€§ãããããã¬ã®ã¥ã¬ãŒã¿ãŒã®åçž®ã溶ããŠç©Žã«ãªããŸãã èšç®ã®è©³çŽ°ã¯ãã¡ã
ãã«ã¹é»å§ã¬ã®ã¥ã¬ãŒã¿ã®æ¹ãåªããŠããŸãããçµå±ã®ãšãããLEDã¯é»å§ã§ã¯ãªãé»æµãå®å®åããå¿ èŠããããŸãã å©ç¹ã¯mikruhaã§ããããšãããããŸããã ããã¯ç§ãããã§èª¬æããæºåã®ç¬¬2éšã§ããã
ãšã¬ã¯ãããã¯ã¹
èŠä»¶ãåŠçããŸããã ããã¯ã¯ãã ããŠãåãæéã§ãã
ç§ã¯é»åå·¥åŠãäžè¬çã«ã¯åå¿è ã§ãã ãã®ãããç§ã¯Acinonyxããåè·¯ãåµé çã«äœãçŽããŸããïŒããã¯VETERAN SCOOTERããåè·¯ãåããŸããïŒã 以äžãå€æŽããå¿ èŠããããŸããã
- æããã¿ã³
- åä¿¡æ©ããPWMå ¥åãååŸãã
- 3ã€ã®ã¬ãã°ATTinyã¯åºåãšããŠèå¥ããLEDãã©ã€ããŒããããã«æ¥ç¶ããŸã
- åžžã«æå¹ã«ãªã4çªç®ã®ãã©ã€ããŒãè¿œå ããŸãïŒBANOã®å ŽåïŒ
äžè¬ã«ããªãªãžãã«ã®æ®ãã¯ã»ãšãã©ãããŸããã
ãã©ã€ããŒãšããŠãZXLD1350è¶ å°ååè·¯ã®äœ¿çšã«æåããŸãããããã¯ãã·ã³ã°ã«ã¯ããLEDïŒæ倧é»æµ350mAïŒã«é»åãäŸçµŠããããã«æ£ç¢ºã«èšèšãããŠããŸãã ããã«ãç·äŸçµŠé»å§ã«ãã¹ãŠããŸãšããŠæè³ããå Žåãåãã£ãã«ã§ä»»æã®LEDãçŽåã«é 眮ã§ããŸãã ã€ãŸã 3SïŒ11.1VïŒããããªãŒããåè·¯ã«çµŠé»ããå Žåãåãã£ã³ãã«ã«æ倧3åã®LEDã眮ãããšãã§ããããããã®3.2VãäžãããŸãã
PWMå ¥åãšåãã¯ã€ã€ã䜿çšããŠãåä¿¡æ©ãšã¯å¥ã«ãã€ã¯ãã³ã³ãããŒã©ãŒã«é»åãäŸçµŠããŸããã

ã¹ããŒã ã åãã£ãã«ã¯ãããŒã¿ã·ãŒãã®ã¹ããŒã ã«åŸã£ãŠæ§ç¯ãããŸãã ããŒãã«ã¯ãã®ãããªãã£ãã«ã4ã€ãããŸãïŒ1ã€ã ãæç»ããŸããïŒã ç§ã¯3ã€ã®LEDãæããŸããããç§ãèšã£ãããã«ãåãã£ãã«ã«ä»»æã®æ°ã®LEDã眮ãããšãã§ããŸãã LEDãç°ãªãè²ïŒç°ãªãé»å§éäžïŒã«ããããšãã§ããŸããäž»ãªããšã¯ãLEDãåãé»æµçšã«èšèšãããããšã§ãã ãã©ã€ãèªäœã¯ããã€ãªãŒããæµããé»æµã350mAãè¶ ããªãããã«ããã®ãããªé»å§ãéžæããŸãã
3ã€ã®ãã£ã³ãã«ã®ADJå ¥åã¯ããã©ã³ãžã¹ã¿ãä»ããŠã³ã³ãããŒã©ãŒåºåã«æ¥ç¶ãããŸãã ZXLD1350ãã©ã€ããŒã«ã¯ãã³ã³ãããŒã©ãŒããLEDããªã³/ãªãã§ããç¹å¥ãªã¡ã«ããºã ããããŸãã ããã«ãå ¥åé»å§ãå€æŽããããPWMã䜿çšããããšã«ãããèŒåºŠãã¹ã ãŒãºã«èª¿æŽã§ããŸãã ããã¯0.3Vãã2.5Vã®æå¹ãªå ¥åé»å§ã§ãããã³ã³ãããŒã©ãã5VãåºåããŸãã 幞ããªããšã«ãããŒã¿ã·ãŒãã§ã¯ããã©ã³ãžã¹ã¿ã®åœ¢ã®ãœãªã¥ãŒã·ã§ã³ãæšå¥šããŠããŸãã ãã®ãã©ã³ãžã¹ã¿ãè«çç¶æ ãå転ãããããšã ããèæ ®ããå¿ èŠããããŸã-ã³ã³ãããŒã©ãŒã®è¶³ã®ãŒãã¯LEDããªã³ã«ãããŠãããããªãã«ããŸãã ãã ããããã¯ããã°ã©ã ã§ä¿®æ£ããåé¡ã§ã¯ãããŸããã
ééãç¯çŽããããã«ãäž¡é¢ããŒããäœæããããšã«ããŸããã ç§ã¯LUTãšã¯åéã«ãªããŸããã§ãããããã©ãã¬ãžã¹ãã§ãã¹ãŠãåããŠããŸããããŸããã ç§ãã¯ãã ãã¹ã¯ã§éãã§ã¿ãŸããããæè¡ã«éåãããã¹ã¯ãç æ°ã«ãªããŸããïŒãããŠãããã€ãã®å Žæã§å®å šã«èœã¡ãŸããïŒã ãšã©ãŒã¯å°æ¥çã«èæ ®ãããŸããããã®è©Šã¿ã¯ãã®ãŸãŸã«ããŸãã ãšã«ããåããŠè»¢ãããŸãã


PCBã¬ã€ã¢ãŠãã 端ã®ååã¯ãããã³ã°ããŒã¯ã§ãã ç§ã¯ãã¯ã¹ãã©ã€ããå°ãäœçœã§åãåããååã®å Žæã«ç©ŽãéããŠãããã¹ã¯ãçµã¿åãããŸããã ç©Žã®éå±åã¯è¡ããããžã£ã³ããŒã管çããŸããã ããŠãã³ã³ãã³ãµãŒã®èã¯åŽé¢éã®ãžã£ã³ããŒãšããŠãæ©èœããŸãã

å®æåã ãã¬ãŒã ã§äœåãªãããœã©ã€ããããªãã³ã°ãããŸããã ãã®çµæã27x22mmã®ã·ã§ãŒã«ãš4gã®ééã«ãªããŸããã ããŠãã¯ã€ã€ãšã³ãã¯ã¿ã®å¥ã®2gãå€æããŸããã ããã€ã¹ã¯ãæšæºã®3ãã³JRã³ãã¯ã¿ãä»ããŠåä¿¡æ©ã«æ¥ç¶ãããŸãã LEDãã©ã€ãã¯ãããããªãŒãã©ã³ã·ã³ã°ã³ãã¯ã¿ããé»åãåãåããŸãã


1Wã¯ZXLD1360ããããå°ãèŠãããšãã§ããŸãã 3W LEDïŒé»æµ750mAïŒã«é»åãäŸçµŠããããã«èšèšãããŠããŸãã é ç·å³ãšãã³é 眮ã¯åãã§ãããããããŒãã®é ç·ãé©åã§ãã äžéšã®ããŒãã®å€ã®ã¿ãå€æŽããå¿ èŠããããŸããããŒã¿ã·ãŒããåžã£ãŠãã ããã
äž¡é¢ããŒãã®ãšããã³ã°ããŸã è¡ã£ãŠããªã人ã®ããã«ãçé¢çšã®ããã€ãã®ãªãã·ã§ã³ãæçš¿ããŸã-ãã£ã³ãã«2ã3ã4ã
ç§ã¯ebeeã§äžåœäººããLEDãè²·ããŸãã ã ã©ãžãšãŒã¿ãŒãªãã§ç¹ã«è³Œå ¥ããŸããããã©ãã«ã§ãåãŸããŸããã ã©ãžãšãŒã¿ãŒãšããŠã¢ã«ãããŠã çã䜿çšããŸããã LEDã¯ãç¹æ®ãªç±äŒå°æ§ããŒããŸãã¯æ¥çå€ã䜿çšããŠåãä»ããããšãã§ããŸãã ããã¯ãã¹ãããŒãžã§ã³ã§ã®å€èŠ³ã§ãïŒããã§ã¯ã©ãžãšãŒã¿ãŒãå°ããããŠã©ãŒã ã¢ããäžã§ãïŒ

ãããŠã以åã®ã¢ãã«ãåæ§ã§ãã

ãã¡ãŒã ãŠã§ã¢
ä»ãããªãã¯ãã®éçã«åœãå¹ã蟌ãå¿ èŠããããŸãã Scooter VETERANããã®ãã¡ãŒã ãŠã§ã¢ã®ãœãŒã¹ãã€ã³ã¿ãŒãããäžã§èŠã€ãããªãã£ãã®ã§ãç§ã¯ãã¹ãŠèªåã§ãããªããã°ãªããŸããã§ããã ãããããã¡ãããäœãå ¥ã£ãŠããããèŠãããã«ãã¡ãŒã ãŠã§ã¢ãå解ããŸããããATTiny13ä»æ§ãèªãã ãã®æ¹ãã¯ããã«äŸ¿å©ã§ããã
ãã€ã¯ãã³ã³ãããŒã©ãŒã«ã¯1KBã®ãã©ãã·ã¥ãããªããšããäºå®ã«ãããããããç§ã¯Cã§æžãããšã«ããŸãããããã¯ãã䟿å©ã§èŠèŠçã§ãã ãã¡ãããArduinoã®ã¹ã±ããã¯äœããã®æ¹æ³ã§ç°¡åã«ãªããŸãããç§ãèšç»ãããã¹ãŠãã³ã³ãããŒã©ãŒã®ã¡ã¢ãªã«åãŸãããã§ã¯ãããŸããã ãããã£ãŠãäžäœã¬ãã«ã«ç§»åããŠãã¬ãžã¹ã¿ãçŽæ¥ããã°ã©ã ããå¿ èŠããããŸããã é©ããããšã«ãã³ã³ãã€ã©ãŒïŒAtmel Studio 6ã®gcc 3.4.2ïŒã¯ããªãè¯ãã³ãŒããçæããŸããã 確ãã«ãã³ã³ãã€ã©ãæé©ã§ã¯ãªãåäœãããå Žæãããã€ããããŸãããããããã®å Žæã¯èª¿æŽããããšãã§ããŸããã
ãã¡ãŒã ãŠã§ã¢ã®ã¢ãŒããã¯ãã£äžã®åé¡ã¯ãããã€ãã®æŠå¿µçã«ç°ãªãã¢ã¯ã·ã§ã³ãåæã«è¡ãå¿ èŠãããããšã§ã-ããã§ç¹æ» ã
å€å žçãªäŸãæããŸãããã 1ã€ã®LEDãç¹æ» ãããå¿ èŠãããå Žåã¯ã©ããªããŸããïŒ ããã§ã¯ãããã°ã©ã ã¯æ¬¡ã®ããã«ãªããŸãã
while(1) { led1(on); delay(500); led1(off); delay(500); }
ãããã2ã€ã®LEDãç¹æ» ãããå¿ èŠããããåšæ³¢æ°ãç°ãªãå Žåã§ãã©ãã§ããããïŒ ãŸãããã¡ãããããªãã¯ãã®ãããªäœããæªæ²ããŠæžãããšãã§ããŸãïŒ
while(1) { led1(on); delay(300); led2(on); delay(200); led1(off); delay(500); led2(off); delay(200); }
ããããã¿ã€ãã³ã°ãšãªã³ãªãã®é åºãéžæããããšã¯éåžžã«é£ããã§ãããã å¯èœã§ããã°ããã¡ããïŒçãããïŒã ãããŠã3ã€ã®ãã€ãªãŒãã§ç¹æ» ããå¿ èŠãããå Žåã¯ã©ããªããŸããïŒ ãããŠ4ã€ïŒ
æ£ãã解決çã¯ã¿ã€ããŒã䜿çšããããšã§ãã ããããåé¡ããããŸãããã€ã¯ãã³ã³ãããŒã©ãŒã®ã¿ã€ããŒã¯1ã ãã§ãããã§ã8ãããã§ãã
å®éãã¿ã€ããŒã1ã€ããå Žåãå€ãã®ãœãããŠã§ã¢ã¿ã€ããŒãäœæã§ããŸãã ãã®ããã«èŠããŸãïŒããŒããŠã§ã¢ã¿ã€ããŒã¯é«åšæ³¢æ°ã§å»ã ãšéããŠããŸãã ã¿ã€ããŒæäœããšã«ããã³ãã©ãŒã¯ãããã°ã©ã ã¿ã€ããŒã®èšå®æéãåãããã©ããã確èªããŸãã å€æããå Žåã¯ããã³ãã©ãŒãåŒã³åºãå¿ èŠããããŸãã
ã³ãŒãã§ã©ã®ããã«èŠãããèŠãŠã¿ãŸãããã
// Pointer to a timer handler typedef void (*eventHandler)(); // Software timers list typedef struct timer_t { uint16_t timeout; eventHandler handler; } timer_t; #define TIMERS_LIST_SIZE 5 timer_t timersList[TIMERS_LIST_SIZE];
ããã°ã©ã ã¿ã€ããŒã¯ãã¡ã€ã³ïŒéïŒã¿ã€ããŒããã³ãã©ãŒãåŒã³åºãåã«ã¹ã¯ããŒã«ããªããã°ãªããªãåæ°ã®ã«ãŠã³ã¿ãŒã§ãã ãã³ãã©ãŒãžã®ãã€ã³ã¿ãŒãæ·»ä»ãããŸãã ãããã®ãšã³ããªã®ãã¡3ã€ã¯ã¿ã¹ã¯ã«ååã§ããã念ã®ããã5ã€ã®èŠçŽ ã®ãµã€ãºã§ããã°ã©ã ã¿ã€ããŒã®ãªã¹ããäœæããŸããã
ãã€ã¯ãã³ã³ãããŒã©ã®ã¿ã€ããŒã®èšå®ã®åé¡ã«ã€ããŠã¯ãå°ãåŸã§èª¬æããŸãã ãããŠä»ããœãããŠã§ã¢ã¿ã€ããŒã®å®è£ ã«ã€ããŠã åæåé¢æ°ã¯ã·ã³ãã«ã«èŠããŸã-ã¿ã€ããŒã®ãªã¹ãããªã»ããããŸã
void setupEventQueue() { // Clear timers list memset(timersList, 0, sizeof(timersList)); }
ããã°ã©ã ã¿ã€ããŒãè¿œå ããã«ã¯ã空ã®ã¹ããããæ¢ããããã«ã¿ã€ã ã¢ãŠãå€ãšãã³ãã©ãŒãžã®ãã€ã³ã¿ãŒãå ¥åããã ãã§ãã ã³ã³ãããŒã©ã®ã¹ããŒã¹ãç¯çŽããããã®ãšã©ãŒãã§ãã¯ã¯ãããŸããã
void addTimer(eventHandler handler, uint16_t timeout) { // Search through the timers list to find empty slot for(timer_t * timer = timersList; timer < timersList + TIMERS_LIST_SIZE; timer++) { if(timer->handler != NULL) continue; // Add the timer to the list timer->handler = handler; timer->timeout = timeout; break; } }
äž»ãªãµã€ã¯ã«ã¯æ¬¡ã®ãšããã§ãã
void runEventLoop() { runTimer(); // Set up sleep mode set_sleep_mode(SLEEP_MODE_IDLE); while(1) // Main event loop { wdt_reset(); // Sleep until the timer event occurs sleep_enable(); sleep_cpu(); sleep_disable(); //Iterate over timers for(timer_t * timer = timersList; timer < timersList + TIMERS_LIST_SIZE; timer++) { // Skip inactive timers if(timer->handler == NULL) continue; if(timer->timeout) // Decrement timeout value { timer->timeout--; } else // If it is already zero - execute handler { timer->handler(); timer->handler = NULL; } } } }
ãŸããã¿ã€ããŒãéå§ããŸãïŒä»¥äžã§è©³ãã説æããŸãããããã»ã©ç°¡åã§ã¯ãããŸããïŒã ç©æ¥µçã«åŸ ã€ã®ã§ã¯ãªããç¡ç ã䜿çšããŸãã åãµã€ã¯ã«ã®éå§æã«ãããã»ããµã¯ã¢ã€ãã«ã¢ãŒãã«å ¥ããŸãã ããã¯ãCPUèªäœãã¹ãªãŒãç¶æ ã«ãªãããšãæå³ããŸããããã¹ãŠã®ã¿ã€ããŒïŒOKããã¹ãŠã1ã€ã§ãïŒïŒã¯åŒãç¶ãåäœããŸãã ã¿ã€ããŒãæåŸãŸã§ã«ãŠã³ããããŒãã«ãªã»ããããããšãå²ã蟌ã¿ãçºçããããã»ããµãèµ·åããŠããã°ã©ã ãããã«é²ã¿ãŸãã å¿ èŠãªãã®ã ãã§ãã
ã¯ããLEDãŠã€ã³ã«ãŒã§å€ãã®é»åãç¯çŽããããšã¯ã§ããŸããããå°æ¥ã¯åããã¬ãŒã ãç ãã«èœã¡ãããšãéåžžã«åœ¹ç«ã€ä»ã®ã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšã§ããŸãã
ç®ãèŠãããããœãããŠã§ã¢ã¿ã€ããŒã®ãªã¹ãã調ã¹ãæéã§ãã åã¬ã³ãŒãã§ãã«ãŠã³ã¿ãŒå€ãæžãããŸãã ãã§ã«ãŒãã«éããŠããå Žåã¯ããã³ãã©ãŒãåŒã³åºãããã®åŸããªã¹ãããã¿ã€ããŒãåé€ããŸãïŒãã³ãã©ãŒãžã®ãã€ã³ã¿ãŒã«NULLãæžã蟌ãããšã«ããïŒã
ãã¹ãŠã1ã€ã®ã¹ã¬ããã§è¡ãããããããã¥ãŒããã¯ã¹ãšããã¯ã¯äžèŠã§ãã
åºå®åšæ³¢æ°ã§LEDãç¹æ» ãããã«ã¯ãããã»ããµã¯æ¬¡ã®ããã«ãªããŸããLEDã®ç¶æ ãå転ããããã°ããããŠããåãããã»ããµãå床åŒã³åºãããã·ã¹ãã ã«èŠæ±ããŸãã
#define LED_A_PIN PORTB0 void toggleLedATask() { PORTB ^= (1 << LED_A_PIN); addTimer(toggleLedATask, TIMEOUT_MS(300)); }
ãããæ©èœããã«ã¯ããã³ãã©ãŒãäœããã®åœ¢ã§åããŠåŒã³åºãå¿ èŠããããŸãã ãããè¡ãã«ã¯ãã¡ã€ã³ã«ãŒããéå§ããåã«ã0ããªç§ã®é 延ïŒã€ãŸããæåã®æ©äŒïŒã§ãã³ãã©ãŒãåŒã³åºãæéã§ãããšããã¡ãã»ãŒãžããã¥ãŒã«å ¥ããŸãã
int main(void) { // Set up ports PORTB = 1 << LED_A_PIN; // LEDs switched off DDRB = 1 << LED_A_PIN; // output mode for LED pins setupEventQueue(); addTimer(toggleLedATask, TIMEOUT_MS(0)); sei(); runEventLoop(); }
ãŸããåºåçšã®ãã³ãããã§æ§æããŸãã LEDã¯ã€ã³ããŒã¿ãä»ããŠæ¥ç¶ãããŠããããšãæãåºãããŠãã ããã ãããã£ãŠãããã©ã«ãã®LEDããªãã«ããã«ã¯ãããŒãã«ãŠããããæžã蟌ãå¿ èŠããããŸãã
ãŸããååŸã«ç¹æ» ããã®ã¯é¢çœããªãã äœããã£ãšãã£ãããïŒ ããšãã°ãäžåºŠãã©ãã·ã¥ããŠãããäžæåæ¢ããåŸã2åç¹æ» ããŠãã3åç¹°ãè¿ããŠãæ¯ã£ãŠãããæ··ããªãã§ãã ããã ãŸãããããé£ãããããŸããã
#define LED_B_PIN PORTB1 uint8_t delayIndex = 0; const uint16_t delays[] = { TIMEOUT_MS(100), //on TIMEOUT_MS(700), //off TIMEOUT_MS(100), //on TIMEOUT_MS(200), //off TIMEOUT_MS(100), //on TIMEOUT_MS(700), //off TIMEOUT_MS(100), //on TIMEOUT_MS(200), //off TIMEOUT_MS(100), //on TIMEOUT_MS(200), //off TIMEOUT_MS(100), //on TIMEOUT_MS(1200), //off }; void complexLedTask() { PORTB ^= (1 << LED_B_PIN); uint16_t delay = delays[delayIndex]; delayIndex ++; if(delayIndex >= sizeof(delays)/sizeof(uint16_t)) //dim(delays) delayIndex = 0; addTimer(complexLedTask, delay); }
ã¿ã€ãã³ã°ã®è¡šãäœæããã ãã§ãã ãã³ãã©ãŒã¯æ¯åãLEDã®ç¶æ ãå€æŽããè¡šã«ç€ºãããŠããæéåŸ æ©ããŸãã
ããã€ãã®LEDãåæã«ç¬ç«ããŠç¹æ» ãããã«ã¯ãããŒããèšå®ããŠãã³ãã©ãŒã®ãªã¹ãã«è¿œå ããããšãå¿ããã«ãããã€ãã®åæ§ã®ãã³ãã©ãŒãè¿œå ããã ãã§ãã
int main(void) { // Set up ports PORTB = 1 << LED_A_PIN | 1 << LED_B_PIN | 1 << LED_C_PIN; // LEDs switched off DDRB = 1 << LED_A_PIN | 1 << LED_B_PIN | 1 << LED_C_PIN; // output mode for LED pins setupEventQueue(); addTimer(toggleLedATask, TIMEOUT_MS(0)); addTimer(complexLedTask, TIMEOUT_MS(0)); addTimer(blinkLedCTask, TIMEOUT_MS(0)); sei(); runEventLoop(); }
ãã¡ããããã®ã¹ã¿ã€ã«ã®ããã°ã©ãã³ã°ã«ãŸã æ £ããå¿ èŠããããŸãããäžè¬ã«ããã®ã¢ãããŒãã¯ããŸãæ©èœããŸãã 倧èŠæš¡ãªã³ã³ãã¥ãŒã¿ãŒçšã®ãã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ãäœæããŠããå Žåãéåžžãåã¹ã¬ããã«ã¯æ°žé ã®ã«ãŒãããããå Žåã«ãã£ãŠã¯äœããã®ã¹ãªãŒããŸãã¯åŸ æ©ããããŸãã äžèšã®ãã³ãã©ãŒã¯åãæ°žé ã®ã«ãŒãã®æ¬äœã§ãããaddTimerïŒïŒåŒã³åºãã¯åãã¹ãªãŒãã§ãããšèããŠãã ããã
ã¡ã€ã³ã¿ã€ããŒã¯ã©ã®ãããã®é »åºŠã§ãã§ãã¯ããå¿ èŠããããŸãã é »ç¹ã«ã«ãã«ãé³ãããŠãªãå Žåã枬å®ãããæéééã®ç²ŸåºŠãäœäžããŸãã äžæ¹ãã¿ã€ããŒãµã€ã¯ã«ããšã«ãäžå®æ°ã®æçšãªã¢ã¯ã·ã§ã³ãå®è¡ããå¿ èŠããããŸãã ãããŠããããã®ã¢ã¯ã·ã§ã³ã¯ã次ã®ã¿ã€ããŒãµã€ã¯ã«ã®åã«å®äºããå¿ èŠããããŸãã ãã®ãããã¿ã€ããŒã¯ã«ãã«ãé³ãããŠãããŸãé »ç¹ã«åãã§ã¯ãããŸããã
ã€ãŸã ãŸãã§ã¯ãããŸããã ããããã©ã®ããã«æ£ç¢ºã«ïŒ ããŠãåã®ã¿ã¹ã¯ã§ã¯ãå¯èœãªå€ã®ç¯å²ã¯éåžžã«åºãã§ãã ãã ãããPWMå ¥åãèãããšããã¿ã¹ã¯ãèŠããŠããå¿ èŠããããŸãã ããå ·äœçã«ã¯ãæç¶æéã800-2200ÎŒsã®ãã«ã¹ãããããã®é·ãã枬å®ããå¿ èŠããããŸãã ã¿ã¹ã¯ã§ã¯ããªã¢ãŒãã³ã³ãããŒã«ããã®ã³ãã³ãã«ãã£ãŠLEDããªã³/ãªãããŸãããããèæ ®ããŸãããã«ã¹ã1500 µsããçãå ŽåãLEDã¯ãªãã«ãªããé·ããªããšãªã³ã«ãªããŸãã
ãã€ã¯ãã³ã³ãããŒã©ãšã¿ã€ããŒã®èšèªã«ç¿»èš³ããŠã枬å®ãããæéã®é·ãã«ã¿ã€ããŒã®ãã£ãã¯ãããã€å ¥ãããã«ãŠã³ãããŸãã ãã®åé¡ã¯ããã«ã¹å¹ ããããå€ã«ã»ãŒçãããšãã«çºçããŸãã ãã®åŸã誀ã£ãã¢ã©ãŒã ãçºçãããã«ã¹é·ãå€ãããšLEDãç¹æ» ããŸãã ãŸã°ããã®å¯èœæ§ãæžããã«ã¯ããã«ã¹é·ãããæ£ç¢ºã«æž¬å®ããå¿ èŠããããŸãã ã¿ã€ããŒã®å解èœã¯1ã2ÎŒsã®ç¯å²å ã«ããã¹ãã ãšæããŸã-ãã®ãããªå解èœã¯æž¬å®ã®ååãªç²ŸåºŠãæäŸããŸãã
ç¹å®ã®æ°å€ã«ã€ããŠè©±ããŠããããããã€ã¯ãã³ã³ãããŒã©ãŒã®åšæ³¢æ°ãææ¡ããå¿ èŠããããŸãã ã³ã³ãããŒã©ãŒã¯ãå éšãžã§ãã¬ãŒã¿ãŒãšå€éšãžã§ãã¬ãŒã¿ãŒããã¯ããã¯ãäŸçµŠã§ããŸãã å€éšãžã§ãã¬ãŒã¿ãŒã¯ããæ£ç¢ºã§ããããããã¯è¿œå ã®è©³çŽ°ãšééã§ãã ã¯ãããããŠæ£ç¢ºãã¯æ¬åœã«å¿ èŠãããŸããã 128kHzã4.8MHzãããã³9.6MHzã¯ãå éšãžã§ãã¬ãŒã¿ãŒããå©çšã§ããŸãã 128kHzã§ã¯ååã§ã¯ãããŸãããä»ã®2ã€ã®ãªãã·ã§ã³ããéžæããŸãã
ã¿ã€ããŒã¯ããã€ã¯ãã³ã³ãããŒã©ãŒãšåãåšæ³¢æ°ãæã€ãã8ã64ã256ããŸãã¯1024ã®ååšåšã䜿çšã§ããŸããã¿ã€ããŒèªäœã¯0ãã255ãŸã§ã«ãŠã³ãããŠãã0ã«ãªã»ãããããŸããååšåšã1ãã£ãã¯ã䜿çšããªãå Žåã¿ã€ããŒã¯1ã€ã®ããã»ããµãã£ãã¯ã«å¯Ÿå¿ããŸããããã¯ã»ãšãã©ã®å Žåã1ã€ã®ã³ãã³ãã«å¯Ÿå¿ããŸãã å®å šãªã¿ã€ããŒãµã€ã¯ã«ããšã«æçšãªäœæ¥ãè¡ãã€ããã§ããã ãããã256ããŒã ããšã«ãã®äœæ¥ãè¡ãå¿ èŠãããå Žåããã®äœæ¥ãè¡ãæéããªãã§ãããïŒãŸãã¯éåžžã«å°ããã¯ãã§ãïŒã
ãããã£ãŠã4.8 MHzãã9.6 MHzãããã³ååšåš8ã64ãããã³256ãéžæããå¿ èŠããããŸããç§ã«ãšã£ãŠã¯ãååšåš8ãåãã4.8 MHzã®ããªãšãŒã·ã§ã³ã¯ããªãè¯ãã§ãã ã¿ã€ããŒã¯ã4.8 MHz / 8 = 600 kHzã®åšæ³¢æ°ã§äœåããŸãã ããã¯ã1ãã£ãã¯ã«1.666mksããããããšãæå³ããŸãã åžæãã1ã2 mkã«ã¡ããã©åãŸããŸãã ãã«ã¿ã€ããŒãµã€ã¯ã«ã«ã¯1,666 * 256 = 426.66ÎŒsããããŸãã ããã°ã©ã ã¿ã€ããŒãšããŠã16ãããå€æ°ã䜿çšããŸããããã¯ãæé65536 * 426.66ÎŒs= 27.96 sã枬å®ã§ããããšãæå³ããŸãïŒåã426.66ÎŒsã®ç²ŸåºŠã§ïŒ
ã¿ã€ããŒéå§ã³ãŒãïŒ
void runTimer() { // Reset timer counter TCNT0 = 0; // Run timer at 4.8MHz/8 = 600 kHz // This gives 1.667 uSec timer tick, 426.667 uSec timer interval // Almost 28 seconds with additional 16bit SW timer value TCCR0A = 0; // Normal mode TCCR0B = 0 << CS02 | 1 << CS01 | 0 << CS00; // run timer with prescailer f/8 }
äžèšã®ã³ãŒãã§ã¯ãäžå¯è§£ãªTIMEOUT_MSãã¯ãã䜿çšããŸããã ããã解èªããæãæ¥ãŸããã
#define TIMEOUT_MS(t) ((uint32_t)t * 600 / 256) //4.8MHz / (8 prescailer * 256 full timer cycle * 1000 since we are counting in ms)
ãã®ãã¯ãã¯ãæå®ãããããªç§æ°ã®æž¬å®ã«å¿ èŠãª426.6ÎŒsã§ãµã€ã¯ã«æ°ã決å®ããŸãã æ®å¿µãªãããå®å šãªåŒïŒè§£èª¬ã«ããåŒïŒã«ã¶ã€ãããšãã³ã³ãã€ã©ã¯åŠçã§ããªãã²ã©ã枊ãçæãå§ããŸããã ä»ã§ã¯ç解ã§ããªã600/256ã«æ°åŒãæ°ãçŽãå¿ èŠããããŸããã
ããããPWMå ¥åã®ãªã¹ãã³ã°ã«æ»ããŸãã ããããããããããã«ããã¹ãŠãã©ã®ããã«æ©èœããããããäžåºŠèª¬æããŸãããèšãæããã°ã ã¡ã€ã³ã®8ãããã¿ã€ããŒã¯0ãã255ãŸã§å»ã¿ãŸããã¿ã€ããŒãµã€ã¯ã«ãå®äºãããã³ã«ãããã°ã©ã ã¿ã€ããŒã®ãªã¹ããåŠçããå¿ èŠã«å¿ããŠãã³ãã©ãŒãå®è¡ããŸãã ããã«ã8ãããã¿ã€ããŒèªäœã®å€ã䜿çšããŠãå ¥åã§ã®ãã«ã¹é·ã枬å®ããŸãã ããã¯éåžžã«ç°¡åã«è¡ãããŸããè¡åãå§ãŸããšãã¿ã€ããŒã®å€ãèšæ¶ããŸãã ãã«ã¹ãé²ããšãã¿ã€ããŒã¯å»ã¿ç¶ããŸãã ãã«ã¹ãçµäºãããŸã§ã«ãã¿ã€ããŒã¯æ°ããå€ã«äœäžããŸãã ãããã£ãŠãå€ã®å·®ã«ããã1ãã£ãã¯ã®æéïŒ1,666ÎŒsïŒãä¹ç®ããã ãã§ãã«ã¹é·ãèšç®ã§ããŸã
ãããŠïŒ 8ãããã¿ã€ããŒããããŸããã€ãŸãããã®æ¹æ³ã§æž¬å®ã§ããã®ã¯æ倧256 * 1.66 = 426.66ãã€ã¯ãç§ã®ãã«ã¹ã®ã¿ã§ãæ倧2200ãã€ã¯ãç§ã®å ¥åãã«ã¹ã§ãã é¢ä¿ãããŸããïŒ å¿ èŠã«å¿ããŠå€ãã®äžäœãã€ããè¿œå ããããšã«ãããã¿ã€ããŒã«ãŠã³ã¿ãŒã人çºçã«æ¡åŒµã§ããŸãã éåžžã®ãã€ããªæŒç®ã¯æ©èœããŸã-äžäœãã€ãããªãŒããŒãããŒãããšãäžäœãã€ããå¢å ããŸãã
// Additional high byte for 8bit timer value volatile uint8_t tcnth; void runTimer() { // Reset timer counters tcnth = 0; TCNT0 = 0; // Run timer at 4.8MHz/8 = 600 kHz // This gives 1.667 uSec timer tick, 426.667 uSec timer interval // Almost 28 seconds with additional 16bit SW timer value TCCR0A = 0; // Normal mode TCCR0B = 0 << CS02 | 1 << CS01 | 0 << CS00; // run timer with prescailer f/8 TIMSK0 = 1 << TOIE0; }
ã»ãšãã©ãã¹ãŠãåãã§ãã tcnthå€æ°ã®ã¿ãè¿œå ãããŸãã-ã¿ã€ããŒå ã®äžäœãã€ãã«å ããŠãäžäœããã€ãã æåŸã®è¡ãéèŠã§ã-ã¿ã€ããŒãªãŒããŒãããŒå²ã蟌ã¿ãå«ãŸããŠããŸãã ãã®å²ã蟌ã¿ã¯ãäžäœãã€ããã€ã³ã¯ãªã¡ã³ãããŸãã
ISR(TIM0_OVF_vect) { // Increment high byte of the HW counter tcnth++; }
tcnthå€æ°ã¯volatile宣èšãããŠããããšã«æ³šæããŠãã ããã ãã®ããŒã¯ãŒãããªããšãããã°ã©ã ã®å¥ã®éšåã®ã³ã³ãã€ã©ãŒã¯ãå€æ°ãå€æŽãããªããšå€æããéå°ãæé©åããå ŽåããããŸãã 圌ã¯ãå€æ°ãå²ã蟌ã¿ïŒå®éã«ã¯å¥ã®ã¹ã¬ããïŒã§å€åããããšãç¥ããŸããã
ãã«ã¹ã®éå§ãšçµäºããã£ããããã«ã¯ããã®ããã«ç¹å¥ã«èšèšããããã³å€æŽå²ã蟌ã¿ã䜿çšã§ããŸããããã¯ãå ¥åã®å€ãå€æŽããããšãã«åŒã³åºãããå²ã蟌ã¿ã§ãã T.O. å ¥åã絶ããããŒãªã³ã°ããå¿ èŠã¯ãããŸãã-ãã€ã¯ãã³ã³ãããŒã©ãŒããã¹ãŠã®äœæ¥ãè¡ããŸãã ãã®å²ã蟌ã¿ã®ãã³ãã©ãŒã®ã¿ãèšè¿°ã§ããŸã
uint16_t pwmPulseStartTime; #define PWM_THRESHOLD 900 // number of pulses in 1500 uS at 4.8MHz with /8 prescailer = 1500 * 4.8 / 8 = 900 // Pin Change interrupt ISR(PCINT0_vect) { /* // Get the current time stamp uint16_t curTime = (tcnth << 8) + TCNT0; Unfortunately gcc generates plenty of code when constructing 16 bit value from 2 bytes. Let's do it ourselves */ union { struct { uint8_t l; uint8_t h; }; uint16_t val; } curTime; // Get the current time stamp curTime.h = tcnth; curTime.l = TCNT0; // It may happen that Pin Change Interrupt occurs at the same time as timer overflow // Since timer overflow interrupt has lower priority let's do its work here (increment tcnth) if(TIFR0 & (1 << TOV0)) { curTime.h = tcnth+1; curTime.l = TCNT0; } if(PINB & (1 << PWM_INPUT_PIN)) // On raising edge just capture current timer value { pwmPulseStartTime = curTime.val; } else // On failing edge calculate pulse length and turn on/off LED depending on time { uint16_t pulseLen = curTime.val - pwmPulseStartTime; if(pulseLen >= PWM_THRESHOLD) PORTB |= (1 << LED_C_PIN); else PORTB &= ~(1 << LED_C_PIN); } }
ãã³ãã©ãŒã®æåã®éšåã¯ãã¿ã€ããŒã«ãŠã³ã¿ãŒã®å€ããã«ããããšã«å°å¿µããŠããŸãïŒè¿œå ã®å€éšãã€ãã«ãã£ãŠæ¡åŒµãããŸãïŒã æ®å¿µãªãããé¡ã®å€ãèªã¿åãããšã¯ã§ããŸããã§ãã-æã ãLEDãèªçºçã«ç¹æ» ããŸããã ããã¯ã2ã€ã®å²ã蟌ã¿ãã»ãŒåæã«çºçããããã§ãã ãŸããã¿ã€ããŒå²ã蟌ã¿ã®åªå 床ã¯äœãããããã³ãã©ãŒã¯å¿ èŠãªãšãã«åŒã³åºãããªãããšããããŸããã ãã®çµæãäžäœãã€ãã¯å¢å ããŸããã§ãããã€ãŸããåèšå€ã¯256åäœå°ãªããªããŸããã ããã¯äžå¯æ¬ ã§ãã
解決çã¯éåžžã«ç°¡åã§ã-ã¿ã€ããŒãªãŒããŒãããŒãçºçãããã©ããã確èªããçºçããå Žåã¯ããªãŒããŒãããŒãã³ãã©ãŒãšåãäœæ¥ãè¡ããŸã-äžäœãã€ãã«+1ããŸãã
ãã®æç¹ã§ãç§ã¯gnatã«ãã£ãŠçæãããã³ãŒãã®éæé©æ§ã«ã€ãŸãããŸããã ã³ãŒãïŒtcnth << 8ïŒ+ TCNT0ã¯ãã®ããã«ã³ã³ãã€ã«ãããã·ãããšè¿œå ãè¡ãããŸãã ãŸããæé©åãå«ãŸããŠããã«ããããããïŒ-O1ïŒã ãã®å Žæã§ã¯ã2ãã€ãã16ãããæ°ãšããŠè§£éããå¿ èŠããããŸãã ç§ã¯çµåã§åºãå²ããªããã°ãªããŸããã§ããã
ãã³ãã©ãŒã®2çªç®ã®éšåã¯ãå®éã«åœ¹ç«ã€ä»äºãããŸãã è¡åã®å§ãŸããæããå Žåã¯ãå€æ°pwmPulseStartTimeã®ã¿ã€ã ã¹ã¿ã³ããèŠããŠãããŠãã ããã ãã«ã¹ã®çµãããæããå Žå-ã¿ã€ã ã¹ã¿ã³ãã®éããèæ ®ããå€ã«å¿ããŠLEDããªã³/ãªãããŸãã å¿çã®ãããå€ã¯1500msãã€ãŸããããã1.66 µsã®ã¿ã€ããŒã®900ãã£ãã¯ã§ãã
ããã§äžè¶³ããŠããã®ã¯ããã®ãã³å€æŽå²ã蟌ã¿ã®åæåã§ãã
#define PWM_INPUT_PIN PCINT3 void setupPWMInput() { // Initialize the timestamp value pwmPulseStartTime = 0; // Set up pin configuration PORTB |= 1 << PWM_INPUT_PIN; // pull-up for PCINT3 DDRB &= ~(1 << PWM_INPUT_PIN); // output mode for LED pins, input mode for PCINT3 pin // Use PCINT3 pin as input PCMSK = 1 << PWM_INPUT_PIN; // Enable Pin Change interrupt GIMSK |= 1 << PCIE; }
ã»ãšãã©ãã¹ãŠã®æºåãæŽããŸãããèŠä»¶ã®ãã¡ãæ»ãããªç¹æ» ã®ã¿ãå®è£ ãããŠããŸãããå®éãã³ã³ãããŒã©ãŒã¯LEDã®ãªã³ãšãªãã®ã¿ãåãæ¿ããããšãã§ããŸããäžéå€ã¯ãããŸãããããããæå®ã®ãã¥ãŒãã£ãµã€ã¯ã«ïŒLEDããªã³ã«ãªã£ãŠããæéãšãªã³ã«ãªã£ãŠããªãæéã®æ¯çïŒã§ãã°ãããã°ãããªã³/ãªããåãæ¿ãããšã人ã¯ãLEDããŸã æ»ããã«èŒããŠããããã«èŠããŸãããèŒåºŠã¯äœããªã£ãŠããŸãããã¥ãŒãã£ãµã€ã¯ã«ãå°ããã€å€æŽãããšãLEDã®èŒåºŠãã¹ã ãŒãºã«å€åããããã«èŠããŸãã
LEDããªã³ãŸãã¯ãªãã«ããã³ãŒããäœæã§ããŸããã¿ã€ããŒã®å©ç¹ã¯ãå¿ èŠãªã ãå®è¡ã§ããããã«ãªããŸããããããããªããPWMçæãæ¢ã«ã³ã³ãããŒã©ãŒã«çµã¿èŸŒãŸããŠããã®ã§ããããïŒããã«ãã¬ãã°OC0Aããã³OC0BïŒPB0ããã³PB1ïŒã§ãæ倧2ã€ã®çæãã£ãã«ãç¬ç«ããŠå¶åŸ¡ã§ããŸãã
ãã®ããã«åäœããŸããåäžã®ã¿ã€ããŒãæå®ã®é床ã§éåžžã©ããå転ããŸãããµã€ã¯ã«ã®éå§æã«ããŠãããã¯1ã«èšå®ãããç¹å®ã®å€ïŒã¬ãžã¹ã¿OCR0Aããã³OCR0Bã§èšå®ïŒã«éãããšããŠãããã¯ãŒãã«èšå®ãããŸãã次ã«ããµã€ã¯ã«ãç¹°ãè¿ãããŸããã¬ãžã¹ã¿ã®å€ã倧ããã»ã©ããã¥ãŒãã£ãµã€ã¯ã«ã倧ãããªãããã€ãªãŒããæãããªããŸããããã¯éå転ã¢ãŒããšåŒã°ããŸãã LEDã¯ã€ã³ããŒã¿ãä»ããŠæ¥ç¶ãããŠãããããå転ã¢ãŒãã®æ¹ãé©ããŠããŸããã¬ãžã¹ã¿ã®å€ããªã³ã«ããã¿ã€ããŒãçµäºããŠãªã»ãããããããªãã«ããŸãã
// Current PWM value volatile uint8_t pwmAValue = 1; volatile uint8_t pwmBValue = 1; void runTimer() { // Reset counter counters tcnth = 0; TCNT0 = 0; OCR0A = pwmAValue; OCR0B = pwmBValue; // Run timer at 4.8MHz/8 = 600 kHz // This gives 1.667 uSec timer tick, 426.667 uSec timer interval // Almost 28 seconds with additional 16bit SW timer value //TCCR0A = 1 << COM0A1 | 1 << COM0A0 | 1 << COM0B1 | 1 << COM0B0 | 1 << WGM01 | 1 << WGM00; // Fast PWM on OC0A and OC0B pins, inverting mode TCCR0A = 1 << COM0A1 | 1 << COM0A0 | 1 << WGM01 | 1 << WGM00; // Fast PWM on OC0A pin, inverting mode TCCR0B = 0 << CS02 | 1 << CS01 | 0 << CS00; // run timer with prescailer f/8 TIMSK0 = 1 << TOIE0; }
ã¿ã€ããŒã®åæåãå°ã調æŽããå¿ èŠããããŸãããWGM00ããã³WGM01ãããã¯ãé«éPWMçæã¢ãŒããæå¹ã«ããŸãããããCOM0A0ãCOM0A1ãCOM0B0ãããã³COM0B1ã¯ããã£ãã«Aããã³Bã®å転ã¢ãŒããæå¹ã«ããŸããããæ£ç¢ºã«ã¯ãã³ã¡ã³ãè¡ã«ã¯ãOC0Aã®ã¿ã®ã³ã¡ã³ããªãã®äž¡æ¹ãå«ãŸããŸãã
pwmAValueå€æ°ã®å€ã¯æã å€åãããããäœããã®æ¹æ³ã§ã¿ã€ããŒã«éç¥ããå¿ èŠããããŸããããã¯ããªãŒããŒãããŒãã³ãã©ã§è¡ãã®ãæé©ã§ãã
ISR(TIM0_OVF_vect) { // Update the PWM values OCR0A = pwmAValue; OCR0B = pwmBValue; // Increment high byte of the HW counter tcnth++; }
ãã¡ãããå€ãçŽæ¥OCR0Aããã³OCR0Bã¬ãžã¹ã¿ã«çŽæ¥ããã·ã¥ã§ããŸãããããã¯ããŒã¿ã·ãŒãã§æšå¥šãããŠããŸãããããã«ããããã³ã®å€ãæ¬æ¥ãããæ©ããŸãã¯é ãå€æŽããããšããã¹ãªããããçºçããå¯èœæ§ããããŸããèŠèŠçã«ã¯ãããã¯æããã®æãŸãããªãã·ã£ãŒãã§çæçãªå€åã«çŸããŸãã
æããèªäœã¯ããã§ã«ããç¥ãããŠãããœãããŠã§ã¢ã¿ã€ããŒã§å€æŽã§ããŸããããšãã°ã次ã®ããã«ïŒ
uint8_t directionA = 0; void pwmLedATask() { if(directionA) // Incrementing { pwmAValue += 2; if(pwmAValue == 255) directionA = 0; } else //decrementing { pwmAValue -= 2; if(pwmAValue == 1) directionA = 1; } addTimer(pwmLedATask, TIMEOUT_MS(2)); }
pwmAValueå€æ°ã®å€ãã€ã³ã¯ãªã¡ã³ããŸãã¯ãã¯ãªã¡ã³ãããã ãã§ãé©åãªã¬ãžã¹ã¿ã«å ¥åãããŸãããã ããå®éã®ç¹æ» ããŒã³ã³ããšãã¥ã¬ãŒãããã«ã¯ããã£ãšããããªãã®ãèãåºãå¿ èŠããããŸããããšãã°ã次ã®ããã«ïŒ
typedef struct complexPWM { uint8_t step; uint8_t maxValue; uint16_t delay; } complexPWM; complexPWM pwmItems[] = { {0, 1, TIMEOUT_MS(1000)}, {2, 127, TIMEOUT_MS(2)}, {-2, 33, TIMEOUT_MS(2)}, {2, 255, TIMEOUT_MS(2)}, {-2, 1, TIMEOUT_MS(2)} }; uint8_t pwmTableIndex = 0; void complexPWMTask() { complexPWM * curItem = pwmItems + pwmTableIndex; pwmAValue += curItem->step; if(curItem->maxValue == pwmAValue) pwmTableIndex++; if(pwmTableIndex == sizeof(pwmItems)/sizeof(complexPWM)) //dim(pwmItems) pwmTableIndex = 0; addTimer(complexPWMTask, curItem->delay); }
ç¹æ» ããããŒã³ã³ã®ããã«èŠãããã©ããã¯ããããŸãããããã®ã³ãŒãã§ã¯ãäºåãã©ãã·ã¥ãæãã127ã§è¡ãããæããã33ã«æžãããŠãã«ãã©ãã·ã¥ïŒæ倧255ïŒã«ããŸãã
ãããããã¡ãŒã ãŠã§ã¢ã®ãã¹ãŠã§ãããã¹ãŠã®gibletsãšmorgulkiã«ããããã¹ãŠã500ã600ãã€ãã«å¹²æžããŸã-äºåãæ®ã£ãŠããŸãã 1ã€ã®éèŠãªãã€ã³ã-ãã¥ãŒãºãããã匷調ããããã«æ®ã£ãŠããŸãããããã¯hfuse = 0xffãlfuse = 0x79ãšåãã§ãããã³ãŒãã«ã€ããŠã¯ãããŒã¿ã·ãŒããèŠæ±ããŸããç°¡åã«èšããšããããã®ãã€ãã®æ°ãããã«ãããã³ã³ãããŒã©ãŒã¯4.8 MHzã§åäœããããã«ãªããŸããæ®ãã®ãããã¯ããã©ã«ãç¶æ ã®ãŸãŸã§ãã
å®éã®å€èŠ³ã¯ãèšäºã®ããããŒã«ãããããªããæšå®ã§ããŸãã
ãããã«
ãã®èšäºã§ã¯ãBANOãçéžç¯ãã²ãŒããªã©ãããŸããŸãªèªç©ºæ©ã¢ãã«ã®é»ççšã®ã³ã³ãããŒã©ãŒã®ããŒãžã§ã³ã«ã€ããŠèª¬æããŸãããããšã¯ãã¡ãŒã ãŠã§ã¢ãå°ãéžã¶ã ãã§ãã³ããŒã¢ãã«ã¯å®éã®ã¢ãã«ã®ããã«èŠããŸãã
ããã«ããã®ãããªãŠã€ã³ã«ãŒã¯è»ã«ä¹ããããšãã§ããŸãããŸããããšãã°ãåºåçæ¿ã匷調衚瀺ã§ããŸãããã¹ãŠãããªãã®æã«ãããŸãã
ããããåäžã®é£è¡æ©ã§ã¯ãããŸãããã©ã€ãã®ç¹æ» ã«å ããŠã匱ãã³ã³ãããŒã©ãŒã®ããã°ã©ãã³ã°ã«é¢é£ããèšäºã§ä»ã®ããã€ãã®ãã€ã³ããåãäžããŸããã
- 1ã€ã®ã¿ã€ããŒã§è€æ°ã®ã¿ã€ããŒãã·ãã¥ã¬ãŒãããæ¹æ³
- ã¿ã€ããŒãªãã·ã§ã³ã®éžææ¹æ³
- PWMçæã¢ãŒãã§ã¿ã€ããŒãèšå®ããæ¹æ³
- PWMå ¥åãèããèªã¿åãå€ã«åºã¥ããŠæçšãªäœæ¥ãè¡ãæ¹æ³
LEDãç¹æ» ãããã¿ã¹ã¯ãç¡èŠãããšããã€ã¯ãã³ã³ãããŒã©ãŒäžã®ããã«ãã¿ã¹ã¯ãïŒããã«ãã¹ã¬ãããïŒïŒã¢ããªã±ãŒã·ã§ã³ã«é©ãããã¬ãŒã ã¯ãŒã¯ã§ããããšãããããŸããããã¡ãããããã¯RTOSã§ã¯ãããŸãããããã§ã«å€ãã®ã«ãŒãã³æäœãæé€ããŠããŸãããã¡ãŒã ãŠã§ã¢ã§ã¯ããã®ãã¬ãŒã ã¯ãŒã¯ãå¥ã®ã¢ãžã¥ãŒã«EventQueue.c / .hã«é 眮ããŸãããå¥åº·ã䜿çšããŠãã ããã
è¯ãç¹ã¯ã3ã€ã®å®å šã«ç¬ç«ããã¿ã¹ã¯ïŒé·æéã®ã«ãŠã³ããå ¥åã§ã®ãã«ã¹å¹ ã®æž¬å®ãåºåã§ã®PWMã®çæïŒãååŸããããšã§ããåäžã®8ãããã¿ã€ããŒã§åŠçã§ããŸãããããŠãè¿œå ããããœãããŠã§ã¢ã¿ã€ããŒã§ã¯ããŸã å€ãã®äŸ¿å©ãªããšãã§ããŸãã
ããããã³ãŒãã¯ããŸãæ§é åãããŠããŸããã§ãããç°ãªãã¿ã¹ã¯ã¯åãæ©èœã§è§£æ±ºãããŸãããåã¿ã¹ã¯ã¯ããã€ãã®å Žæã«åæ£ãããŸããããããããã¯ã³ã³ãã¯ããªãµã€ãºã®æéã§ããåæ§ã«ããã¿ã³ãæ å ±ãå ¥åããä»ã®æ段ã®æ¬ åŠãããããããäžåºŠãããã°ã©ããŒã®ã¯ã€ã€ãŒãã³ã³ãããŒã©ãŒã«çŽæ¥ã¯ãã ä»ãããã³ãŒãã§ç®çã®ç¹æ» ãªãã·ã§ã³ãæ§æããããããã¹ãŠãã¡ãŒã ãŠã§ã¢ã®åœ¢ã§æ³šã蟌ãã®ã«ããããããŠããŸããã
ãã®èšäºã¯åèè³æã§ã¯ãããŸãããç¹å®ã®ããããšã¬ãžã¹ã¿ã®èª¬æã®ããã«ããŒã¿ã·ãŒãã«ã¢ã¯ã»ã¹ããå¿ èŠã¯ãããŸãããããã¯ãAVRã©ã€ã³ã®ãžã¥ãã¢ã³ã³ãããŒã©ãŒã®ããããªæ段ã䜿çšããŠæçšãªãã®ãäœæããæ¹æ³ã®äžäŸã§ãã
æåã¯ãæçµçãªã³ã³ãã€ã«æžã¿hexãã¡ã€ã«ãèšäºã«æ·»ä»ããäºå®ã¯ãããŸããã§ãããäºå®ã¯ããã¹ãŠã®ã¢ãã«ãç°ãªããšããããšã§ããå¥ã®æ°ã®ãã£ãã«ãå¿ èŠãªå Žæãå¥ã®ç¹æ» ãå¿ èŠãªå Žæãããã€ãã®å ¥åãè¿œå ããå¿ èŠãããããŸãã¯å¥ã®æäœãè¡ãå¿ èŠãããå ŽåããããŸãã代ããã«ãèªåã®èãã«å®å šã«äžèŽããããã«èªåã§ãã¡ãŒã ãŠã§ã¢ãå€æŽããããšããå§ãããŸããããã¯ãã¹ãŠã·ã³ãã«ã§ãïŒ
ãã ãããã¹ãŠã®èªç©ºæ©ã¢ãã©ãŒãã³ã³ãã€ã©ãšåéã§ããããã§ã¯ãããŸãããã ããç§ã¯ããã§ãããã€ãã®äžéããŒãžã§ã³ãã³ã³ãã€ã«ããŸããïŒ1ã€ã®ãã£ã³ãã«ã2ç§ããšã«ç¹æ» ïŒã¹ãããïŒããPWMãã£ã³ãã«ãäºéç¹æ» ã§ããå°ãé »ç¹ã«ç¹æ» ãã3ã€ç®ã®ãã£ã³ãã«ã¯ãªã¢ã³ã³ããã®ã³ãã³ãã«ãã£ãŠãªã³ã«ãªããŸãããã®ãã¡ãŒã ãŠã§ã¢ã¯ãããã«dopilivaniyaã®éå§ç¹ã«ãªããŸããç§ãã³ãŒãã«æ®ããèšäºã«ç€ºãããŠããäŸã¯ãåŒã³åºãã«ã€ããŠã®ã¿ã³ã¡ã³ãããŠããŸãã
é 匵ã£ãŠïŒ
ãã¡ãŒã ãŠã§ã¢ãœãŒã¹ãšPCBã¬ã€ã¢ãŠãã