Sending data from Master to Slave

Hi, I am working on a project which is designed to test 4 wire PWM Fans. I have been asked to use two Arduino Uno, as Master and Slave. I found a working code from a forum posted by @dlloyd . As I read through the forum, I found the PWM signals are being generated by a subroutine called void pwmDuty (). My question is, how do I send the PWM signals to the slave Arduino? I usedboth the wire.Write(ocrb) and wire.Write(pwmDuty) but it shows error. Any help will be great!

Fan datasheet

#include <Wire.h>

unsigned long startTime;
int pwmOut=3;
int pwm=0 ;
int duty;
byte ocrb;
int half_revolutions = 0;
int rpm = 0;
unsigned long lastmillis = 0;
 int i=0;
 int minim = 12000;
 int maxim = 0;
 int Judgment=0;
 int Delta=0;

 
float DutyCycle; 
void setup()
{
  pwm25kHzBegin();
  Serial.begin(9600);
  pinMode(pwmOut, OUTPUT);
  Wire.begin();
  attachInterrupt(0, rpm_fan, FALLING);
}

void loop(){
  // pwmDuty(19); // 25% (range = 0-79 = 1.25-100%)
 // delay(5000);
//  pwmDuty(39); // 50% (range = 0-79 = 1.25-100%)
 // delay (5000);
  pwmDuty(11); // 75% (range = 0-79 = 1.25-100%)
  if (millis() - lastmillis == 1000){ //Uptade every one second, this will be equal to reading frecuency (Hz).
 
 detachInterrupt(0);//Disable interrupt when calculating
 if (i<20) {
 //for (i; i<21; i++) { 
 rpm = half_revolutions * 30; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.
 if ( rpm > maxim ) maxim =rpm;
    if ( rpm < minim ) minim = rpm;
 Serial.print("RPM =\t"); //print the word "RPM" and tab.
 Serial.println(rpm); // print the rpm value.
 //Serial.print("\t Hz=\t"); //print the word "Hz".
 //Serial.println(half_revolutions); //print revolutions per second or Hz. And print new line or enter.
 if ( i == 19 ){
  if (minim<4050) Judgment=1;
  if (maxim>4950) Judgment=1;
  Delta=maxim-minim;
  if (Delta>600) Judgment=1;
   Serial.print ("Min=\t");
   Serial.print(minim);
   Serial.print ("\t Max=\t");
   Serial.println(maxim);
   Serial.print ("\t Delta=\t");
   Serial.println(Delta);
   if (Judgment==1) Serial.println("Fail");
   else Serial.println ("Pass");
   
 }
 i++;
 half_revolutions = 0; // Restart the RPM counter
 lastmillis = millis(); // Uptade lasmillis
 
 attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
  }
   Wire.beginTransmission(1);
    delay(11);
   
   Wire.write(pwmDuty);
   Wire.endTransmission();
   delay(50);
 
    }
void pwm25kHzBegin() {
  TCCR2A = 0;                               // TC2 Control Register A
  TCCR2B = 0;                               // TC2 Control Register B
  TIMSK2 = 0;                               // TC2 Interrupt Mask Register
  TIFR2 = 0;                                // TC2 Interrupt Flag Register
  TCCR2A |= (1 << COM2B1) | (1 << WGM21) | (1 << WGM20);  // OC2B cleared/set on match when up/down counting, fast PWM
  TCCR2B |= (1 << WGM22) | (1 << CS21);     // prescaler 8
  OCR2A = 79;                               // TOP overflow value (Hz)
  OCR2B = 0;
}
void pwmDuty(byte ocrb) {
  OCR2B = ocrb; }        
void rpm_fan(){
  half_revolutions++;
}

Why would You do that?........
Your presentation is too vague. Give us the big picture! Please draw things like block diagrams etc. Don't post poetry, novells...

You can't do it that way. pwmDuty is a function

  1. What you're currently are doing is passing the pointer to the function. Your statement should be something like Wire.write(pwmDuty(x)); where x is the number that you want to transfer.
  2. That function does not return anything so whatever you're transferring will be random garbage.

Your code contains this line

  pwmDuty(11); // 75% (range = 0-79 = 1.25-100%)

So it sets something to 11. That 11 is what you want to transfer and your Wire.write() will become

Wire.write(11);

Now it's stupid to use magic numbers for that. So I suggest that you add a variable byte dutyCycle; near the top of your code; to prevent confusion, remove the float DutyCycle;.

And use that new variable. in loop()

  dutyCycle = 11;
  pwmDuty(dutyCycle);

  ...
  ...
  Wire.write(dutyCycle);

You can now change the value of dutyCycle variable, e.g. based on calculations.

Do you know why they asked you to use 2 Arduinos? If not, ask them. This should quite easily be done with one Arduino.

After I asked, I was told it is because the Master Arduino will be constantly sending PWM pulse to Slave which then sends it to the Fan. While doing this, the Master Arduino will be reading RPM values from speed wire of the fan simultaneously.

Thank you very much for the clarification. I will try and let you know the result.

PWM is implemented in hardware. So your slave is free to do anythings else at exactly the same time; I don't think that your slave will have a problem measuring the RPM at the same time.

Hi, just wanted to update. Instead of using Wire.h library and making connection. I just used 3 different output pins from 1st Arduino to 2nd Arduino. For example pin 7,8,9. These pins go high and low in 100, then 010, and 001 form. The 2nd Arduino takes these input and then produces the PWM output based on the input. 0%, 50%, 100%. Maybe I didn't even needed master slave connection afterall. Anyway thanks for the help. Good day.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.