ããã«ã¡ã¯ãHabrïŒ
ååãããã³ã³ãã¥ãŒã¿ãŒããšã°ãŒã¯ãã£ãïŒã¯ãªã¹ãã¹ããªãŒã¬ãŒã©ã³ããªã©ïŒã«ç°¡åã«æ¥ç¶ãããã®ããã®C / C ++ããã°ã©ã ãæ§ç¯ããããã®ç°å¢ãå±éããæ¹æ³ã«ã€ããŠæžããŸããã ä»æ¥ã¯ãOpenWRTããããã£ãŠBlack Swiftçšã®Cããã°ã©ã ãäœæããæ¹æ³ã®2çªç®ã®éšåã§ãã
- C / C ++ã§ã®OpenWRTã®ã¬ãŒã©ã³ããBlack Swiftæ¥ç¶ããã³ãã«ãç°å¢
- Cå¶åŸ¡ããã°ã©ã ãšçŽæ¥ãã€é«éãªGPIOæäœ
- Web UIãšAndroidã¢ããª
2ã€ã®ç¹ã«æ³šæããŠãã ããã ãŸããã¡ã€ã³é¢æ°ãš#includeãã£ã¬ã¯ãã£ãã®åœ¹å²ã«ã€ããŠã¯èª¬æããŸãã-å
ã»ã©èšã£ãããã«ãä»ã¯ååãšããŠããã°ã©ãã³ã°ã«ç²ŸéããŠããããã³ã³ãã¥ãŒã¿ãŒã®ãããªãã®ã«ã©ã¡ãã®åŽã«ã¢ãããŒãããã®ãããããªã人ã
ã«åºã¥ããŠæžããŠããŸãçµã¿èŸŒã¿çšéåãã ãã£ãšæ£ç¢ºã«èšããšãä»æ¥ã®ããã¹ãã¯ãã§ã«è¿ã¥ããŠãã人ã«ãšã£ãŠããå¯èœæ§ãé«ãã®ã§ãè«çå
¥åºåã©ã€ã³ïŒGPIOïŒããã€ã¯ãç§æéã®æäœãªã©ãããã€ãã®èå³æ·±ãç¹ã«çŠç¹ãåœãŠãŸãã

第äºã«ããã¡ãããCã§æžãå¿
èŠã¯ãããŸããã OpenWRTã®äžã«ã¯PerlãPythonãããã«Node.jsããããŸãããããã¯å¿
èŠãããŸããããœãããŠã§ã¢ãæ§ç¯ããããã®ç°å¢ã¯ãªãã@ runãã¢ããããŒãããã ãã§ãã
GPIOã䜿çšããè¿
éã§ç°¡åãªäœæ¥
ãã¢ã§åäœãã4ã€ã®ããŒãããªããžãã©ã€ããŒã«ãã£ãŠå¶åŸ¡ãããã¯ãªã¹ãã¹ããªãŒã¬ãŒã©ã³ããæã«æã£ãŠããŸãã1ã€ã®ãã¢ã¯ã¬ãŒã©ã³ãã®1ã€ã®æã®æ¥µæ§ãèšå®ãã極æ§ã¯ã°ããŒã®è²ã決å®ããŸãã æããã«ãããã䜿çšããã«ã¯ããã«ã¹å¹
å€èª¿ãå¿
èŠã§ãååã«å
·äœçã§ããå¿
èŠããããŸã-é察称ãã€ãŸãåæéäžã«å極æ§ãç°ãªãæéã«ãªã³ã«ãªããŸãïŒæãåçŽãªå Žå-極æ§ã1ã€ã ãäžãããšãã¬ãŒã©ã³ãã®ã°ããŒã®è²ã1ã€ã ãã«ãªããŸãïŒ ã
ãã®ã¹ããŒã ã¯ãé¡ã«æ¢è£œã®PWMã¢ãžã¥ãŒã«ãé©çšããããšãå°é£ã«ããŸãïŒOpenWRTã«ã¯1ã€ãããŸãïŒ-察称çãªä¿¡å·ãçæããŸããã€ãŸããæ倧ã®æ倧å€ã¯ãè²ãç¬ç«ããŠå¶åŸ¡ããããšãªãããã¹ãŠã®è²ã§ã¬ãŒã©ã³ãå
šäœã®æãããåæã«èª¿æŽããããšã§ãã ãããã£ãŠãPWMã¯èªåã§è¡ãå¿
èŠããããŸãã
PWMã¯ãåºæ¬çãªã¬ãã«ã§ã¯ããã®ãµã€ã¯ã«ã§ã¯ãæãåçŽãªã±ãŒã¹ã§ã¯ãããã»ããµã®ã¬ãã°ãçŽ æ©ãåããã ãã§ãã
while (true) { if (value > 0) gpioSet(GPIO_NUMBER, 1); for (int i=1; i<=100; i++) if (value == i) gpioSet(GPIO_NUMBER, 0); }
æå³ã¯æããã ãšæããŸããå€ãvalueãã§ãã¬ãŒã©ã³ãã®LEDã®æããã§è¡šçŸãããç®çã®ãã¥ãŒãã£ãµã€ã¯ã«ãèšå®ããŸãïŒæ¥µæ§å転ãšè²ç®¡çã«ã¯ãŸã 觊ããŠããŸããïŒã
Linuxã®gpioSetïŒint gpioãintã¬ãã«ïŒé¢æ°ã®æšæºã³ã³ãã³ãã¯ãæšæºsysfsã€ã³ã¿ãŒãã§ãŒã¹ãä»ããŠGPIOã¬ãã°ããã«ããŸããåºåNã1ã«èšå®ããã«ã¯ããŠããããç䌌ãã¡ã€ã«/ sys /ã¯ã©ã¹/ gpio / gpioN /å€ã«æžã蟌ã¿ãŸãã ãã®åã«ã/ sys / class / gpio / exportã«æ°å€Nãèšè¿°ããŠããŠãŒã¶ãŒãgpioNã䜿çšã§ããããã«ãã/ sys / class / gpioN / directionã«ãoutããšããåèªãå
¥åããŠããã®GPIOã®ã¢ãŒãããåºåãã«èšå®ããŸãã
ãã®æé ã«ã¯æ°åã®èª¬æã
ãããŸã ãããšãã°ã
ãã®ãã¡ã®1ã€ã§ã ã
void gpioSet(int gpio, int value) { sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); fd = open(buf, O_WRONLY); sprintf(buf, "%d", value); write(fd, buf, 1); }
ãã®æ¹æ³ã¯åçŽã§ãæ®éçã§ãïŒãã¡ã€ã«ã«æžã蟌ãããšãã§ããªãèšèªãèŠã€ããããšã¯å°é£ã§ãïŒãã
éåžžã«é
ãã§ãã ããã䜿çšããŠè±èŒªãå¶åŸ¡ããå Žåãæçµçã«4æ¬ã®èïŒ2çµã®ããŒãããªããžïŒãåŒãã®ã«éåžžã«æéããããããã400 MHzããã»ããµãæèŒããBlack Swiftã®PWMåšæ³¢æ°ã¯çŽ100 Hzã«ãªããäœèŒåºŠã§ã¯LEDãã¯ã£ãããšç¹ç¯ããŸãã¡ãã€ãã®ã¯äžå¿«ã§ã-äžè¬ã«å¯Ÿçãã¹ããããå§ããŸãã
幞ããªããšã«ãããè¯ãæ¹æ³ããããŸãã 幞ããªããšã«ãããã»ã©é£ããã¯ãããŸãããç°¡åã§ãã ç°¡åã§ãã
void gpioSet(int gpio, int value) { if (value == 0) *(GPIO_ADDR + 4) = (1 << gpio); else *(GPIO_ADDR + 3) = (1 << gpio); }
ç§Theã¯ãããã»ããµå
ã®GPIOãã¬ãžã¹ã¿ãä»ããŠå¶åŸ¡ãããããšã§ããã¬ãžã¹ã¿ã䜿çšãããã¹ãŠã®æäœã¯ã¬ãžã¹ã¿ãä»ããŠè¡ãããŸãã ãŸããã¬ãžã¹ã¿ã¯éåžžã®ã¡ã¢ãªã«ããããããŸãã éåžžã®ã¡ã¢ãªã¯ãéåžžã®ããã€ã¹/ dev / memããçŽæ¥å©çšã§ããŸãã ãããã£ãŠãå¿
èŠãªã®ã¯ãmmapã䜿çšããŠç®çã®å°ããªããŒã¹/ dev / memãã¡ã¢ãªã«ããããïŒã¡ã¢ãªã«ã¡ã¢ãª...ãŸããŸãïŒããã®ããŒã¹ã®å¿
èŠãªãããããã«ããããšã§ãã
if ((m_mfd = open("/dev/mem", O_RDWR) ) < 0) return -1; m_base_addr = (unsigned long*)mmap(NULL, GPIO_BLOCK, PROT_READ|PROT_WRITE, MAP_SHARED, m_mfd, GPIO_ADDR); close(m_mfd);
ã¬ãžã¹ã¿ã®ã¡ã¢ãªãžã®ãããã³ã°ã¯ãããã»ããµã®ããŒã¿ã·ãŒãã«èšèŒãããŠããŸã; AR9331ã®å Žåãã¢ãã¬ã¹ã¯GPIO_ADDR = 0x18040000ïŒ
65ããŒãž ïŒã§å§ãŸã
ãŸã ã ãŸããããŒã¹1ã®+3ããã³+4ã®ã¢ãã¬ã¹ã«ãé¢å¿ããããŸã-GPIOçªå·ã«å¯Ÿå¿ãããããã«ãŠããããæžã蟌ããšãæåã®ã¢ãã¬ã¹ã§GPIOã1ã«èšå®ããã2çªç®ã®ã¢ãã¬ã¹ã§0ã«ãªã»ãããããŸãïŒããããã°ã+ 2ã®ã¬ãžã¹ã¿ããããŸãGPIOããªã»ããããŠã€ã³ã¹ããŒã«ã§ããŸã-ç®çã®ãããã«0ãŸãã¯1ãæžã蟌ãå¿
èŠããããŸãïŒã GPIOã®æ¹åã¯ãããŒã¹ã¢ãã¬ã¹ã®ãããã§èšå®ãããŸãïŒåºåã®å Žåã¯1ãå
¥åã®å Žåã¯0ïŒã
泚æïŒäžéšã®GPIOã¯å€æ©èœã§ãããããã¯å¥ã®ã¬ãžã¹ã¿ã«èšå®ãããŸããããšãã°ãGPIO 9ã§UARTããªãã«ãããŸã§ãéåžžã®å
¥åºåã®ããã«ã¯æ©èœããŸããã ãŸããGPIO 13ã17ã¯å
¥åãšããŠäœ¿çšã§ããŸããã
ã¹ããŒãïŒ äºéé察称PWMã®4ã€ã®GPIOã«ããçæ£-çŽ4.5 kHzã sysfsã§äœæ¥ããŠãããšãã®çŽ100 Hzã«å¯ŸããŠãç§ã¯æãåºããŸãã
ããã¹ãªãŒãã«ããPWMåšæ調æŽ
æããã«ããã®ãããªé床ã®ãã€ãžãŒãã§ãŒã³å¶åŸ¡ã¯å¿
èŠãããŸããã100Hzãè¶
ãããã®ã¯ãã¹ãŠãç¹ã«äœèŒåºŠã§ã¯ããã¯ãã倱ããªããå Žåã«æé©ã§ãïŒGPIOã§çŽæ¥åäœããŸããïŒã é
延ãå°å
¥ããå¿
èŠããããŸãã nanosleepïŒïŒtwãNULLïŒé¢æ°ã䜿çšããŠãæšæºçã«çãé
延ãå
¥åãããŸãã
struct timespec tw; tw.tv_sec = 0;
çè«çã«ã¯ãããã§ã¯ãåPWMã¯ããã¯ãµã€ã¯ã«ããšã«10ÎŒsã®é
延ãåèš100ã¯ããã¯ãµã€ã¯ã«-åèš1 msããŸãã¯1 kHzã®PWMåšæ³¢æ°ïŒè¶³ã®ããããã®ãªãŒããŒããããèæ
®ããªãïŒãååŸããå¿
èŠããããŸãã ã³ã³ãã€ã«ããå®è¡ããçŽ140ã150 HzãååŸããŸãã
åé¡ã¯ãOpenWRTããã³ãã®ãããªããã»ããµã§å®æçã«ç¶æãããæå°ã®ããã¹ãªãŒãæéãçŽ60ÎŒsã§ããããšã§ãã ã€ãŸããé¢æ°ã«tw.tv_nsec = 0ãæž¡ããŠããã¹ã¬ããã¯60ÎŒsé
ããªããŸãã
幞ããªããšã«ãéåžžã«æ£ç¢ºã§ã¯ãªãåå§çãªãã®ããããŸãããããã«å¯ŸåŠããããã®æå¹ãªæ¹æ³ïŒnanosleepïŒNULLãNULLïŒã®åŒã³åºãã«ã¯çŽ3ÎŒsããããŸãã
void nsleep(unsigned long nsecs) { if(nsecs == 0) { nanosleep(NULL,NULL); return; } struct timespec ts; ts.tv_sec=nsecs / 1000000000L; ts.tv_nsec=nsecs % 1000000000L; nanosleep(&ts,NULL); } const int nsleep0_factor=3000; const int nsleep1_factor=70; void _usleep(unsigned long usecs) { if (usecs == 0) return; unsigned long value = (usecs*1000) / nsleep0_factor; if (value > nsleep1_factor) { nsleep((value-nsleep1_factor) * nsleep0_factor); value = value % nsleep1_factor; } for (unsigned long i=0; i < value; ++i) nsleep(0); }
ãã®çµæã_usleepã70ãã€ã¯ãç§æªæºåŒã³åºããšãnanosleepãéåžžåŒã³åºãããšã¯ãããŸããããnanosleepïŒNULLãNULLïŒãäœåºŠãã¹ã¯ããŒã«ããã ãã§ãååŒã³åºãã«ã¯3ãã€ã¯ãç§ããããŸãã ããã¯å€§ãŸããªã§ãããç§ãã¡ã®ç®çã®ããã«ãããããæ£ç¢ºã«å¿
èŠãšããŸããïŒé«å質ã®PWMãå¿
èŠãªå Žåããªã¢ã«ã¿ã€ã ã¢ãŒããä¿èšŒããã·ã¹ãã ã§ãã¹ãŠåãããŒããŠã§ã¢ãŸãã¯ãœãããŠã§ã¢ãè¡ãå¿
èŠããããŸã-ããšãã°ãUARTãä»ããŠéåžžã®ATTinyãBlack Swiftã«æ¥ç¶ããïŒã
ããŠãäžè¬ã«ãåºæ¬çãªããªãã¯ã¯æºåãã§ããŠããŸã-åšæ³¢æ°ã100ãã«ããŸãã¯2ãã«ãã®å®å
šã«å®å®ãããœãããŠã§ã¢PWMãäœæã§ããŸãã
ãŸãããã®PWMã§2çµã®ããŒãããªããžãå¶åŸ¡ããããšãæãåºããŸãããããã¯ãã§ã«äžè¬çã§ãïŒ
for (int i = 0; i < 100; i++) { for (int j = 0; j < 2; j++) { if (i == floor((float)gpioValuePos/brightness)) { gpioSet(gpio[2*j], GPIO_OFF); gpioSet(gpio[2*j+1], GPIO_OFF); } if (i == (100 - floor(((float)gpioValueNeg/brightness)))) { gpioSet(gpio[2*j], GPIO_OFF); gpioSet(gpio[2*j+1], GPIO_ON); } } _usleep(PWM_PERIOD); }
gpioValuePosãšgpioValueNegã¯2ã€ã®æ¥µæ§ã®å€ã§ãïŒãã¡ããããããã®åèšã100ãè¶
ããŠã¯ãªããªããšããæ¡ä»¶ã§ïŒãæãã-ããã¯ãã¬ãŒã©ã³ãå
šäœã®æãããããã«èª¿æŽã§ããããã«ããããã«äºåã«å®ãããã®ã§ãã åãã¬ãã«ã®2ã€ã®GPIOã«ã€ã³ã¹ããŒã«ããããšã¯ãã¬ãŒã©ã³ãããªãã«ããããšãšåãã§ãã
ãã«ãšãã€ãã¹ã«
ã¬ãŒã©ã³ããå¶åŸ¡ããã¢ããªã±ãŒã·ã§ã³ã«ã¯ãä»ã«äœãå¿
èŠã§ããïŒ
第äžã«ãæããã¯æéã®çµéãšãšãã«äœããã®åœ¢ã§å€åããã¯ãã§ãããããã€ãã®ããã°ã©ã ãããæ¹ãè¯ãã§ãã ããªãã¯ããªãèªèº«ã®ã¹ã¯ãªããèšèªãäœãããšãã§ããŸããç§ã¯ãããç°¡åã«ããŸãã-ç§ã¯ã³ãŒãã«3次å
é
åãæ¿å
¥ããŸããããã®äžã«6ã€ã®ããã°ã©ã ããããã4ã€ã®æ®µéã§ãããããã®2ã€ã®ãã¢ã§ä¿åãããŸã-1ã€ã®æ¥µæ§ã®åæèŒåºŠå€ãšãã®å€åã®é床ã ã¯ããã¬ãŒã©ã³ãã®äž¡æ¹ã®ãã©ã³ãã¯åæããŠåäœããŸãã
int prg[PROGRAMS][4][4] = { { {0, 1, 0, 0}, {99, -1, 0, 0}, {0, 0, 0, 1}, {0, 0, 99, -1} }, { {0, 1, 0, 0}, {0, 0, 0, 1}, {0, 1, 0, 0}, {0, 0, 0, 1} }, { {99, -1, 0, 1}, {0, 1, 99, -1}, {99, -1, 0, 1}, {0, 1, 99, -1} }, { {99, 0, 0, 0}, {99, 0, 0, 0}, {99, 0, 0, 0}, {99, 0, 0, 0} }, { {0, 0, 99, 0}, {0, 0, 99, 0}, {0, 0, 99, 0}, {0, 0, 99, 0} }, { {49, 0, 50, 0}, {49, 0, 50, 0}, {49, 0, 50, 0}, {49, 0, 50, 0} } };
ã€ãŸããããšãã°ãæåã®ããã°ã©ã -ã+ããã£ã³ãã«ã®èŒåºŠãåŸã
ã«å¢å ãããã®åŸåŸã
ã«äœäžãã次ã«ã-ããã£ã³ãã«ã®èŒåºŠãå¢æžããŸãã ç°¡åã«èšãã°ã1ã€ã®è²ããã§ãŒãã€ã³ããã³ãã§ãŒãã¢ãŠãããå¥ã®è²ãåæ§ã«ã¹ã ãŒãºã«ãã§ãŒãã€ã³ããã³ãã§ãŒãã¢ãŠãããŸãã åŸè
ã§ã¯ããã¹ãŠã®è²ã®ãã¹ãŠã®LEDãåžžã«ç¹ç¯ããŠããŸãã
次㫠ãããã«ã¯Black Swiftå
šäœããããŸãã®ã§ãWi-Fiå¶åŸ¡ãè¡ããŸãããã ãããŠãIPã¢ãã¬ã¹ã®ãªãã¯ãªã¹ãã¹ããªãŒã¬ãŒã©ã³ãããã£ãŠããæçµçã«ã¹ããŒããã©ã³ã¢ããªã±ãŒã·ã§ã³ã¯ã©ã®ãããªãªã¿ã¯ã§ããïŒ äžè¬ã«ãéåžžã®Webãžã®ã€ã³ã¿ãŒãã§ãŒã¹ãäœæããå¿
èŠããããŸãã
æè¡çã«æãç°¡åãªæ¹æ³ã¯ãUNIXãœã±ãããä»ããŠãå°ãªããšãPHPãããå°ãªããšãã³ãã³ãã©ã€ã³ããïŒsocatãŠãŒãã£ãªãã£ã䜿çšããŠïŒããã·ã¥ã§ããã³ãã³ããæ¬äŒŒãã¡ã€ã«ã§å¶åŸ¡ããããšã§ãã
mode_t mask = umask(S_IXUSR | S_IXGRP | S_IXOTH); int s, s2, len; unsigned int t; struct sockaddr_un local, remote; if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { printf("Socket error\n"); return -1; } int flags = fcntl(s, F_GETFL, 0); fcntl(s, F_SETFL, flags | O_NONBLOCK); local.sun_family = AF_UNIX; strcpy(local.sun_path, "/tmp/treelights.sock"); unlink(local.sun_path); len = strlen(local.sun_path) + sizeof(local.sun_family); if (bind(s, (struct sockaddr *)&local, len) == -1) { printf("Socket bind failed\n"); return -1; } if (listen(s, 5) == -1) { printf("Socket listen failed\n"); return -1; } umask(mask);
ããã«ãããã®ã¯ãã¹ãŠäºå®äžãã³ãã¬ãŒãã§ããWebãµãŒããŒãšã¢ããªã±ãŒã·ã§ã³ãç°ãªããŠãŒã¶ãŒã§åäœããã·ã¹ãã ã§ã¯ãæåãšæåŸã«umaskã䜿çšããæäœãå¿
èŠã§ããããšã®ã¿ã説æããŸãã OpenWRTã§ã¯ãããã©ã«ãã§ã¯ããã§ã¯ãªãããã¹ãŠãã«ãŒãã®äžã«ãããŸãã ãœã±ããã®éããããã³ã°æäœãåºæ¬ã§ããããããªããšãæåã®åŒã³åºãã§å
šå¡ãç«ã¡äžãããäœãããœã±ããã«èœã¡ããŸã§åŸ
æ©ããŸãã
PWMå
ã«ããœã±ããã«è©²åœãããã®ã®åŠçã³ãŒããæ¿å
¥ããŸãã
s2 = accept(s, (struct sockaddr *)&remote, &t); if (s2 > 0) { int i = recv(s2, sockinput, 25, 0); sockinput[i] = 0;
ãã®èãã¯æ確ã ãšæããŸãã ãbrightness 2ããœã±ãããæ¿å
¥ããŸã-è±èŒªã®æãããååã«ããŸãã ä»ã®ã³ãã³ãã®åŠçãåæ§ã«è¿œå ãããŸãã
ä»ã«äœãè¿œå ããŸããïŒ ãããã°äžã®æåèµ·åã®äŸ¿å®ã®ããã«ãããã°ã©ã ãCtrl-Cããã³ãã®ä»ã®ç§»åèŠæ±ã«æ£ããå¿çããããã«ããŸãã
do_exit = 0; static struct sigaction act; sigemptyset (&act.sa_mask); act.sa_flags = 0; act.sa_handler = SIG_IGN; sigaction (SIGHUP, &act, NULL); act.sa_handler = cleanup; sigaction (SIGINT, &act, 0); act.sa_handler = cleanup; sigaction (SIGTERM, &act, 0); act.sa_handler = cleanup; sigaction (SIGKILL, &act, 0); while (!do_exit) {
ãããŠãé¢æ°ãè¿œå ããŸãïŒ
void cleanup(int sig) { do_exit = 1; }
ããã§ãOSããå²ã蟌ã¿èŠæ±ã§å°çããä¿¡å·ãdo_exitå€æ°ã1ã«åãæ¿ããPWMãµã€ã¯ã«ãçµäºããŸãïŒãã¡ãããdo_exitã¯ã°ããŒãã«å€æ°ãšããŠå®£èšãããšããã§ãããïŒã
äžè¬ã«ãããã§ãã¹ãŠã§ãã èŒåºŠå¶åŸ¡ãè€æ°ã®äœæ¥ããã°ã©ã ãWebããŒã¹ã®å¶åŸ¡ãåããé察称PWMãæ§ç¯ããããã®æ¢è£œã®ã¬ã³ã¬ããããŸãã
çµæã¯ããã«ãããŸãïŒ
https :
//github.com/olegart/treelights ïŒOpenWRTããã³ãããžã§ã¯ãèªäœã®Makefileãå«ãïŒïŒããã¯ãLinuxã§ãœãããŠã§ã¢ããã«ãããããã®éåžžã®Makefileãšåãã§ãïŒã èªè
ã®ãªã¯ãšã¹ãã«å¿ãããããªã¯ã第3éšã«ãããŸãïŒãã ããè±èŒªã¯èŠãŠããŸããããäœã§ããïŒïŒã
ãã¡ãããäžèšã®ãã¹ãŠã¯ãã¹ãŠã®OpenWRTã«ãŒã¿ãŒãšããã³ã³ãã¥ãŒã¿ãŒã«é©çšãããŸããã1ã€ã®æ³šæç¹ããããŸããBlackSwiftã®å Žåãéåžžã®100 Hzã«å¯ŸããŠ1000 Hzã®ã¿ã€ããŒã§ããªãšã³ããã£ããã«ãã¿ã¹ã¯ãæå¹ã«ããŠã³ã¢ãæ§ç¯ããŸãã ããããªããã°-æšæºã³ã¢ã§ã¯-PWMã¯ã·ã¹ãã ã®è² è·ãããã£ãŠãé
ããªãããå®å®æ§ãäœäžããŸãã
ãã ããOpenWRTçšã®ãã¡ãŒã ãŠã§ã¢ã®ã¢ã»ã³ããªã«ã€ããŠã¯ãå¥ã®æ©äŒã§ãã