2017-02-08 8 views
0

5kHz +/- 5 %로 PWM 출력을 실현해야합니다. (아마 내가 제어 할 수없는 필터 회로로 인해).ESP8266 5 kHz PWM 구현 방법은 무엇입니까?

ESP8266 (이상적으로 NodeMCU 사용)으로 실현할 수 있습니까?

ESP8266의 소프트웨어 PWM은 최대 주파수가 1kHz이고 시그마 - 델타는 약 300kHz의 고정 주파수를 갖는 PWM을 구현하는 데 사용될 수 있다는 것을 알고 있습니다.

5 kHz를 달성 할 수있는 확실한 방법이 있습니까? 파형 출력을 위해 I2S 주변 장치를 실험 한 사람들이 있지만 5kHz 출력에 사용할 수 있는지 여부는 확실하지 않습니다.

누구나 전에 비슷한 문제를 쳐다 보았습니까?

+0

'analogWriteFreq (5000);'가 도움이됩니까? – dandavis

답변

1

필수 코드는 다음과 같습니다

#define qap  2  // Quick As Possible ... Duty cycle only 0, 50, 100% 
#define HFreq 5150 
#define pPulse D2  // a NodeMCU/ESP8266 GPIO PWM pin 
analogWriteRange(qap); analogWriteFreq(HFreq); analogWrite(pPulse, 1); // start PWM 

TL; DR 그냥 80 MHz 클럭과

//  had HFreq=126400 with 75 KHz pulse at 80 MHz ESP clock, every 1 sec but proof of evidence lost 

명목상 일부 원유 benchamrks에게

했다

// 72.24 KHz 361178 2015061929 
// 72.23 KHz 361163 2415062390 
// 72.23 KHz 361133 2815062824 

있어

160MHz 클록

주의!
1. 듀티 사이클 범위는 2입니다!
2. 시스템에는 다른 컨디셔닝이 없었기 때문에 직렬 IO 등에서 다른 타이밍 아티팩트가 여전히 존재했습니다. 특히 WDT 및 WiFi로 인한 불안정성이 두 번째로 나타났습니다. (여하튼, 아마도 이것은 ESP8266 스트레스와 협박 만하는 문제가있다.)

// 141.50 KHz 353754 619466806 
// 141.52 KHz 353810 1019467038 
//  ... 
// ad infinitum cum tempore finitum, infinitus est ad nauseum? 
//  ... 
// 141.54 KHz 353857 735996888 
// 
// ets Jan 8 2013,rst cause:4, boot mode:(1,7) 
// 
//wdt reset 

5 KHz의 사각 파 신호를 생성하기 위해 다음과 같은 코드를 사용하여 고려 상기 문제없고하지 나오다.

// ------------ test results for 80 MHz clock -------------- 
// 
// 
//  PWM pulse test  
// 
// F_CPU:   80000000L 
// ESP8266_CLOCK: 80000000UL 
// PWM "freq.": 5150 
// 
// 
// connect D1 to D2 
// 
// 
//    raw  MPU  
// frequency count cycle 
// 0.00 KHz 1 407976267 
// 4.74 KHz 9482 567976702 
// 5.00 KHz 10007 727977137 
// 5.00 KHz 10006 887977572 
// 5.00 KHz 10006 1047978007 
// 5.00 KHz 10007 1207978442 
// 5.00 KHz 10006 1367978877 
// 5.00 KHz 10006 1527979312 
// 5.00 KHz 10007 1687979747 
// 5.00 KHz 10006 1847980182 
// 5.00 KHz 10006 2007980617 
// 5.00 KHz 10007 2167981052 
// 5.00 KHz 10006 2327981487 
// 5.00 KHz 10006 2487981922 
// 5.00 KHz 10007 2647982357 ... 
// 
// crude testing for 5KHz signal 
//   extracted from: 
//    highest frequency/shortest period pin pulse generate/detect test 
// 
//  uses raw ESP8266/NodeMCU V1.0 hardware primitive interface of Arduino IDE (no included libraries) 
// 
//  timing dependencies: WDT, WiFi, I2S, I2C, one wire, UART, SPI, ... 
// 
// Arduino GPIO 16 5 4 0 2 14 12 13 15 3 1  0 1 2 3 4 5 ... 12 13 14 15 16 
// NodeMCU D pin 0 1 2 3 4 5 6 7 8 9 10  3 10 4 9 2 1 ... 6 7 5 8 0 
//     | | | | | | | | | | |      
// a   WAKE | | F Tx1 | | Rx2 Tx2 Rx0 Tx0    
//  k  (NO PWM or | | L blue | | | |        
//  a' interrupt) | S  A * H | H | H | |      * led's 
//  s   red S D  S  S M S H  
//     * C A  H  C I I C      
//      L T    L S M S 
//       K A    K O O    
//          └ - - - - └----UART's----┘   
//      └--I2C--┘   └-----SPI------┘ 
// 
// rules of engagement are obscure and vague for effects of argument values for the paramters of these functions: 
//  analogWriteRange(qap);  analogWriteFreq(HFreq);    analogWrite(pPulse, 1); 
// 
// http://stackoverflow.com/questions/42112357/how-to-implement-esp8266-5-khz-pwm 
// 
// system #defines: F_CPU ESP8266_CLOCK 
#define pInt  D1   // HWI pin: NOT D0 ie. GPIO16 is not hardwared interrupt or PWM pin 
#define pPulse D2   // PWM pulsed frequency source ... ditto D0 (note: D4 = blue LED) 
#define countFor 160000000UL 

#define gmv(p) #p   // get macro value 
#define em(p) gmv(p)  // evaluate macro 
#define qap  2   // minimal number of duty cycle levels (0, 50, 100%) Quick As Possible ... 
#define HFreq 5150 //((long int) F_CPU==80000000L ? 125000 : 250000)  // ... to minimize time of a cycle period 
            // max values ^ and ^ found empirically 
//  had HFreq=126400 with 75 KHz pulse at 80 MHz ESP clock, every 1 sec but proof of evidence lost 
#define infoTxt (String)             \ 
        "\n\n\t PWM pulse test  "      \ 
        "\n F_CPU:   " em(F_CPU)       \ 
        "\n ESP8266_CLOCK: " em(ESP8266_CLOCK)     \ 
        "\n PWM \"freq.\": " + HFreq + "\n"     \ 
        "\n\n connect " em(pInt) " to " em(pPulse) "\n"  \ 
        "\n\n    raw  MPU "      \ 
        " \n frequency count cycle " 

long int oc=1, cntr=1; 
unsigned long int tc=0; 
void hwISR(){ cntr++; }            // can count pulses if pInt <---> to pPulse 
void anISR(){ tc=ESP.getCycleCount(); timer0_write(countFor + tc); oc=cntr; cntr=1; } 

void setup() {          // need to still confirm duty cycle=50% (scope it or ...) 
    noInterrupts(); 
     Serial.begin(115200); Serial.println(infoTxt); delay(10); // Serial.flush(); Serial.end(); // Serial timing? 
     analogWriteRange(qap);  analogWriteFreq(HFreq);    analogWrite(pPulse, 1); // start PWM 
     pinMode(pInt, INPUT); attachInterrupt(pInt, hwISR, RISING);        // count pulses 
     timer0_isr_init();   timer0_attachInterrupt(anISR);  anISR();     // 
    interrupts(); 
} 

void loop() { delay(10);  if (oc==0) return; 
       Serial.println((String)" "+(oc/1000.0*F_CPU/countFor)+" KHz "+oc+" "+tc); oc=0; } 
//