Несколько ШИМ-выходов от одного таймера - Arduino - PullRequest
0 голосов
/ 30 октября 2019

Я строю проект, в котором я хочу управлять 2 различными 120-мм 4-контактными вентиляторами с помощью Arduino Mega 2560.

Я хотел бы прочитать обороты обоих вентиляторов, а затем для каждого вентилятора установить для волны ШИМ значениеконтролировать его скорость. Вот что у меня есть.

unsigned long previousRPMMillis;
unsigned long previousMillis;
unsigned long lastRPMmillis1 = 0;
unsigned long lastRPMmillis2 = 0;

volatile unsigned long pulses1=0;
volatile unsigned long pulses2=0;
const int readPin1 = 19;
const int readPin2 = 20;

const int pwmPin1 = 2;
const int pwmPin2 = 3;

int state = 0;

// Set the duty-cycle
void analogWrite25k(int value)
{
    //OCR5C = value; //This is to pin 44
    //OCR3C = value; //This is to pin 3
    OCR3B = value; //This is to pin 2
}


void countPulse1() {
  // just count each pulse we see
  // ISRs should be short, not like
  // these comments, which are long.
  pulses1++;
}

void countPulse2() {
  // just count each pulse we see
  // ISRs should be short, not like
  // these comments, which are long.
  pulses2++;
}


unsigned long calculateRPM(int fanNum) {
  float elapsedMS;
  unsigned long RPM;
  unsigned long revolutions;
  noInterrupts();
  if (fanNum == 1) {
    elapsedMS = (millis() - lastRPMmillis1)/1000.0;
    revolutions = pulses1/2;
    lastRPMmillis1 = millis();
    pulses1 = 0;
  }
  else if (fanNum == 2)  {
    elapsedMS = (millis() - lastRPMmillis2)/1000.0;
    revolutions = pulses2/2;
    lastRPMmillis2 = millis();
    pulses2 = 0;    
  }
  float revPerMS = revolutions / elapsedMS;
  RPM = revPerMS * 60.0;
  interrupts();
  return RPM;
}


void setup() {
  Serial.begin(115200);

  // Set up the RPM read
  pinMode(readPin1,INPUT_PULLUP);
  pinMode(readPin2,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(readPin1), countPulse1, RISING);
  attachInterrupt(digitalPinToInterrupt(readPin2), countPulse2, RISING);

  // Set up the PWM
    TCCR3A = 0;
    TCCR3B = 0;
    TCNT3  = 0;

    // Mode 10: phase correct PWM with ICR5 as Top (= F_CPU/2/25000)
    // OC4C as Non-Inverted PWM output
    ICR3   = (F_CPU/25000)/2;
    OCR3C  = ICR3/2;                    // default: about 50:50
    OCR3B  = ICR3/2;  
    TCCR3A = _BV(COM3B1) | _BV(WGM31);//B - pin2, C - pin 3
    TCCR3B = _BV(WGM33) | _BV(CS30);


    // Set the PWM pin as output.
    pinMode( pwmPin2, OUTPUT);
    pinMode( pwmPin1, OUTPUT);


}

void loop() {
  int w = Serial.parseInt();
    if (w>0) {
        analogWrite25k(w);
        Serial.println(w);
        state = w;
    }

  if (millis() - previousMillis > 1000) {
  Serial.print("Fan1 RPM = ");
  Serial.print(calculateRPM(1));
  Serial.print(" Fan2 RPM = ");
  Serial.println(calculateRPM(2));
  previousMillis = millis(); 
  }
}

Это будет считывать оба RPM, но будет выводить только ШИМ-волну на одном выводе. Я знаю, что это ссылка: https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf

Но я надеюсь, что кто-то знает, как быстро настроить битовые регистры для этого, чтобы мне не пришлось изучать более 30 страниц деталей.

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...