topbanner.gif
Login
Username

Password




Not a member yet?
Click here to register.

Forgotten your password?
Request a new one here.
Shoutbox
You must login to post a message.

09/21/2021 8:53 AM
Welcome, Jantaray !

09/20/2021 2:29 AM
Good morning pouring EllaMandalis, Kyle, thegrantickle, and welcome !

09/16/2021 2:18 PM
leekindo, Kian and nvalley, Welkome !

09/14/2021 9:18 AM
TheHobo, Bigtuna and kilaw, welcome to forum

09/10/2021 8:14 AM
Welcome, hakan and flugsio !

In Memory Of Ginny
Donations

Latest Donations
JackH - 25.00
snwcmpr - 10.00
Anonymous - 2.00
Anonymous - 5.00
Anonymous - 5.00
Users Online
Guests Online: 12

Members Online: 0

Total Members: 7,326
Newest Member: Jantaray

View Thread

Who is here? 1 guest(s)
 Print Thread
Testing Arduino UNO with bitwisetech / popc and MAX6675
renatoa
Before making the things too complicate, may I ask what's the point of fan control through Artisan ?
miyankizu

Quote

renatoa wrote:

Before making the things too complicate, may I ask what's the point of fan control through Artisan ?


Actually I didnít want to mix the thing I just want to thank both of you and sharing another source that may help about fan control. Personally I prefer manual control on fan according to my experiences. Sorry if I disturb
renatoa
No worries, no disturbance.
The question is open, anyone having an answer can share his thoughts.
zamunda
Hello Renatoa,

Thanks for this pointer!

I understand from these lines that I have to build the logic based on target value and current value.

I guess that "target = (au16data[5] / 100.0) * 255)" but how can I get the current value from Artisan back so I can compare it with the target and build the steps based on their difference? Hope you get my point.

Thanks in advance!


Quote

renatoa wrote:

The slew fan logic is here, at line 406:

https://github.co...reader.cpp

target is the final speed you want to reach
this routine should be called in the main loop, after any fan speed change, until target reached.
renatoa
current is a variable you keep in your sketch, not taken from Artisan.
And target is the value from ModBis register 5, you guessed right, when slider from Artisan move, the new value will be sent via ModBus to you.
The slew logic will compare the current fan speed value with new target, and, if different, will increase/decrease current variable value by slew step. The new current value will be sent to fan control circuit.
Edited by renatoa on 08/11/2021 6:06 AM
zamunda

Quote

@zamunda is possible to share motor shield and arduino connection on basic drawing.


Will be happy to share the connections. In fact, i did it according the enclosed diagram, leaving out the connections for the second motor AND leaving the 12V jumper in place.

I have some doubts about the way I connected it (though it is workingGrin).
The fan is driven with a 18V DC power supply and so according the specs I have to remove the 12V jumper.
However, if I do that, it does not work so I have to look into that.

Besides, I use this board only for testing but I think this is a very old motor driver board and I doubt whether it can be used in a "production environment"...
If anyone could advice on a better alternative (maybe the MD10C?) I would be gratefull!

Thanks and regards,
zamunda attached the following image:
controlador-paso-a-paso-l298n-conexiones.jpg

Edited by zamunda on 08/10/2021 8:44 AM
zamunda

Quote

zamunda wrote:

[quote]@zamunda is possible to share motor shield and arduino connection on basic drawing.
I have some doubts about the way I connected it (though it is workingGrin).
The fan is driven with a 18V DC power supply and so according the specs I have to remove the 12V jumper.
However, if I do that, it does not work so I have to look into that.


I found out how it works, jumper should be removed (since DC voltage >12V) but then board should be powered with a 5V from the Arduino (please see attached image).
This should help/overcome burning the board in case of high current/voltage.

Quote


Besides, I use this board only for testing but I think this is a very old motor driver board and I doubt whether it can be used in a "production environment"...
If anyone could advice on a better alternative (maybe the MD10C?) I would be gratefull!


Having understood how this works and having made the adjustment, will give this board a chance and keep testing.
Furthermore, if I can follow up Renatoa's suggestion how avoid big current draw (slew fan logic), it is worth trying.
Regards,
zamunda attached the following image:
controlador-paso-a-paso-l298n-conexiones_1.jpg

Edited by zamunda on 08/10/2021 1:36 PM
miyankizu
@zamunda thank you again :)
zamunda

Quote

renatoa wrote:

current is a variable you keep in your sketch, not taken from Artisan.
And target is the value from ModBis register 5, you guessed right, when slider from Artisan move, the new value will be sent via ModBus to you.
The slew logic will compare the current fan speed value with new target, and, if different, will increase/decrease current variable value by slew step. The new current value will be sent to fan control circuit.


Hello Renatoa,

OK, thanks, I think I'll understand, try to work that out!

Regards,
Edited by renatoa on 08/11/2021 6:06 AM
zamunda
Hello Renatoa,

Quote

renatoa wrote:

current is a variable you keep in your sketch, not taken from Artisan.
And target is the value from ModBis register 5, you guessed right, when slider from Artisan move, the new value will be sent via ModBus to you.
The slew logic will compare the current fan speed value with new target, and, if different, will increase/decrease current variable value by slew step. The new current value will be sent to fan control circuit.


Studied the code for the TC4 and modified my sketch like this (see below). Does not seem to work though...
Any suggestions?

Thanks!



#include <max6675.h>
#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[16] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1
};

/**
    Modbus object declaration
    u8id : node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI
                 or any pin number > 1 for RS-485
*/
Modbus slave(1, 0, 0); // this is slave @1 and RS-232 or USB-FTDI

// Pins for thermocouple MAX6675
int thermoDO = 6;
int thermoCS = 5;
int thermoCLK = 4;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

// declare variable for Arduino pin connected to solid state relay (SSR)
int relay = 9;

// declare variables for Arduino pins connected to fan controller (L293N)
int fan = 10; // ENA of L239N
int in1 = 11; // IN1 of L239N
int in2 = 12; // IN1 of L239N

// declare variables for Arduino pins to power MAX6675:
int vccPin = 3; // 5v power of MAX6675
int gndPin = 2; // gnd of MAX6675

// slew rate limitations for fan control
#define MAX_SLEW 25 // percent per second
#define SLEW_STEP 5 // increase in steps of 5% for smooth transition
#define SLEW_STEP_TIME (uint32_t)(SLEW_STEP * 1000 / MAX_SLEW) // min ms delay between steps

int target = 0;
int current = 0;
int last_fan_change = millis();


void slew_fan() { // limit fan speed increases
  target= ((au16data[5] / 100.0) * 255);
  if( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    uint32_t delta_ms = millis() - last_fan_change; // how long since last step?
    if( delta_ms > SLEW_STEP_TIME ) { // do only if enough time has gone by
     analogWrite(fan, (current - delta ));
    }
  }
  else if( target > current ) {  // ramping up, so check rate
    uint8_t delta = target - current;
    if( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    uint32_t delta_ms = millis() - last_fan_change; // how long since last step?
    if( delta_ms > SLEW_STEP_TIME ) { // do only if enough time has gone by
     //write current fan value for air control
     analogWrite(fan, (current + delta ));
    } 
  }
}

void setup() {
  slave.begin( 19200); // 19200 baud, 8-bits, even, 1-bit stop
  // use Arduino pins
  pinMode(relay, OUTPUT);
  pinMode(fan, OUTPUT);
  //fan direction can be reversed by interchanging values for in1 and in2
  pinMode(in1, OUTPUT); digitalWrite(in1, HIGH);
  pinMode(in2, OUTPUT); digitalWrite(in2, LOW);

  pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);
  delay(500);
}

void loop() {
  //write current thermocouple value
  au16data[2] = ((uint16_t) thermocouple.readCelsius() * 100);

  //write current fan value for air control
  //analogWrite(fan, (au16data[5] / 100.0) * 255);
  slew_fan();
   
  //poll modbus registers
  slave.poll( au16data, 16 );

  // heater control:
  digitalWrite(relay, HIGH);
  delay(au16data[4] * 10);
  digitalWrite(relay, LOW);
  delay((100 - au16data[4]) * 10 - 1);
}

Edited by zamunda on 08/11/2021 9:01 AM
renatoa
Well, the slew logic should not have been taken so literally from TC4, because there the slew routine is called very fast, every some milliseconds, while in your case the main loop take more than one second.
So things are a lot simpler, without those last change checks, as I tried sketch below:


void slew_fan() { // limit fan speed increases
  target= ((au16data[5] / 100.0) * 255);
  if( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
     analogWrite(fan, (current - delta ));
    }
  }
  else if( target > current ) {  // ramping up, so check rate
    uint8_t delta = target - current;
    if( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
     //write current fan value for air control
     analogWrite(fan, (current + delta ));
    }
  }
}


Because speed changes are applied so slow, probably will be a good idea to change SLEW_STEP to 10, my guess.
Please, give it a try and tell us how it works.
zamunda

Quote

renatoa wrote:

Well, the slew logic should not have been taken so literally from TC4, because there the slew routine is called very fast, every some milliseconds, while in your case the main loop take more than one second.
So things are a lot simpler, without those last change checks, as I tried sketch below:


void slew_fan() { // limit fan speed increases
  target= ((au16data[5] / 100.0) * 255);
  if( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
     analogWrite(fan, (current - delta ));
    }
  }
  else if( target > current ) {  // ramping up, so check rate
    uint8_t delta = target - current;
    if( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
     //write current fan value for air control
     analogWrite(fan, (current + delta ));
    }
  }
}


Because speed changes are applied so slow, probably will be a good idea to change SLEW_STEP to 10, my guess.
Please, give it a try and tell us how it works.


Hello Renatoa,

If I copy your code literally, I get:
exit status 1
expected unqualified-id before 'else'

So I guess it should be:



void slew_fan() { // limit fan speed increases
  target= ((au16data[5] / 100.0) * 255);
  if( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if( delta > SLEW_STEP ) { // limit the step size
      delta = SLEW_STEP;
     analogWrite(fan, (current - delta ));
    }
  }
  else if( target > current ) {  // ramping up, so check rate
    uint8_t delta = target - current;
    if( delta > SLEW_STEP ) { // limit the step size
      delta = SLEW_STEP;
     //write current fan value for air control
     analogWrite(fan, (current + delta ));
    }
  }
}



Now it compiles, the code does initiate the fan after moving the slider but stays there at a very low level...

I copy the complete sketch once again below, a big thanks as usual for any hint!




#include <max6675.h>
#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[16] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1
};

/**
    Modbus object declaration
    u8id : node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI
                 or any pin number > 1 for RS-485
*/
Modbus slave(1, 0, 0); // this is slave @1 and RS-232 or USB-FTDI

// Pins for thermocouple MAX6675
int thermoDO = 6;
int thermoCS = 5;
int thermoCLK = 4;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

// declare variable for Arduino pin connected to solid state relay (SSR)
int relay = 9;

// declare variables for Arduino pins connected to fan controller (L293N)
int fan = 10; // ENA of L239N
int in1 = 11; // IN1 of L239N
int in2 = 12; // IN1 of L239N

// declare variables for Arduino pins to power MAX6675:
int vccPin = 3; // 5v power of MAX6675
int gndPin = 2; // gnd of MAX6675

// slew rate limitations for fan control
#define SLEW_STEP 10 // increase in steps of 10% for smooth transition
int target = 0;
int current = 0;

void slew_fan() { // limit fan speed increases
  target= ((au16data[5] / 100.0) * 255);
  if( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if( delta > SLEW_STEP ) { // limit the step size
      delta = SLEW_STEP;
     analogWrite(fan, (current - delta ));
    }
  }
  else if( target > current ) {  // ramping up, so check rate
    uint8_t delta = target - current;
    if( delta > SLEW_STEP ) { // limit the step size
      delta = SLEW_STEP;
     //write current fan value for air control
     analogWrite(fan, (current + delta ));
    }
  }
}

void setup() {
  slave.begin( 19200); // 19200 baud, 8-bits, even, 1-bit stop
  // use Arduino pins
  pinMode(relay, OUTPUT);
  pinMode(fan, OUTPUT);
  //fan direction can be reversed by interchanging values for in1 and in2
  pinMode(in1, OUTPUT); digitalWrite(in1, HIGH);
  pinMode(in2, OUTPUT); digitalWrite(in2, LOW);

  pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);
  delay(500);
}

void loop() {
  //write current thermocouple value
  au16data[2] = ((uint16_t) thermocouple.readCelsius() * 100);

  //write current fan value for air control
 // analogWrite(fan, (au16data[5] / 100.0) * 255);
 slew_fan();

  //poll modbus registers
  slave.poll( au16data, 16 );

  // heater control:
  digitalWrite(relay, HIGH);
  delay(au16data[4] * 10);
  digitalWrite(relay, LOW);
  delay((100 - au16data[4]) * 10 - 1);
}
renatoa
Nope, below is right:

void slew_fan() { // limit fan speed increases
target= ((au16data[5] / 100.0) * 255);
if( target < current ) { // ramping down, so check rate
uint8_t delta = current - target;
if( delta > SLEW_STEP ) // limit the step size
delta = SLEW_STEP;
analogWrite(fan, (current - delta ));
}
else if( target > current ) { // ramping up, so check rate
uint8_t delta = target - current;
if( delta > SLEW_STEP ) // limit the step size
delta = SLEW_STEP;
//write current fan value for air control
analogWrite(fan, (current + delta ));
}
}

Forgt some extra } without the matching left brackets
zamunda

Quote

renatoa wrote:

Nope, below is right:

void slew_fan() { // limit fan speed increases
target= ((au16data[5] / 100.0) * 255);
if( target < current ) { // ramping down, so check rate
uint8_t delta = current - target;
if( delta > SLEW_STEP ) // limit the step size
delta = SLEW_STEP;
analogWrite(fan, (current - delta ));
}
else if( target > current ) { // ramping up, so check rate
uint8_t delta = target - current;
if( delta > SLEW_STEP ) // limit the step size
delta = SLEW_STEP;
//write current fan value for air control
analogWrite(fan, (current + delta ));
}
}

Forgt some extra } without the matching left brackets


Thanks for your reply, I copied in your snippet, compiled and uploaded but still get the same behaviour: it seems to initiate but does not step up or step down, it hangs on an initial low level, fan does not even turn.

I include the complete last code once again since there may be an error elsewhere or logic problem.

Thanks!



#include <max6675.h>
#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[16] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1
};

/**
    Modbus object declaration
    u8id : node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI
                 or any pin number > 1 for RS-485
*/
Modbus slave(1, 0, 0); // this is slave @1 and RS-232 or USB-FTDI

// Pins for thermocouple MAX6675
int thermoDO = 6;
int thermoCS = 5;
int thermoCLK = 4;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

// declare variable for Arduino pin connected to solid state relay (SSR)
int relay = 9;

// declare variables for Arduino pins connected to fan controller (L293N)
int fan = 10; // ENA of L239N
int in1 = 11; // IN1 of L239N
int in2 = 12; // IN1 of L239N

// declare variables for Arduino pins to power MAX6675:
int vccPin = 3; // 5v power of MAX6675
int gndPin = 2; // gnd of MAX6675

// slew rate limitations for fan control
#define SLEW_STEP 10 // increase in steps of 10% for smooth transition
int target = 0;
int current = 0;

void slew_fan() { // limit fan speed increases
  target = ((au16data[5] / 100.0) * 255);
  if ( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if ( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    analogWrite(fan, (current - delta ));
  }
  else if ( target > current ) { // ramping up, so check rate
    uint8_t delta = target - current;
    if ( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    //write current fan value for air control
    analogWrite(fan, (current + delta ));
  }
}


void setup() {
  slave.begin( 19200); // 19200 baud, 8-bits, even, 1-bit stop
  // use Arduino pins
  pinMode(relay, OUTPUT);
  pinMode(fan, OUTPUT);
  //fan direction can be reversed by interchanging values for in1 and in2
  pinMode(in1, OUTPUT); digitalWrite(in1, HIGH);
  pinMode(in2, OUTPUT); digitalWrite(in2, LOW);

  pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);
  delay(500);
}

void loop() {
  //write current thermocouple value
  au16data[2] = ((uint16_t) thermocouple.readCelsius() * 100);

  //write current fan value for air control
  // analogWrite(fan, (au16data[5] / 100.0) * 255);
  slew_fan();

  //poll modbus registers
  slave.poll( au16data, 16 );

  // heater control:
  digitalWrite(relay, HIGH);
  delay(au16data[4] * 10);
  digitalWrite(relay, LOW);
  delay((100 - au16data[4]) * 10 - 1);
}
zamunda
Hello,

I think I found (part) of the problem why the slew()-function did not work as expected.

Within the slew_fan the value for "current" should be updated after each cycle otherwise it stays at its initial value. So I added "current = current - delta;" and "current = current + delta;" respectively after the analogWrite for the fan.

Now it steps to the desired target value!

@renatoa: Still have some doubt whether the fan should have it's own delay value since it now depends on the delay of the heater at the end of the loop. Am I right here?

Thanks in advance!

Regards.



void slew_fan() { // limit fan speed increases
  target = ((au16data[5] / 100.0) * 255);
  if ( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if ( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    analogWrite(fan, (current - delta ));
    current = current - delta;
  }
  else if ( target > current ) { // ramping up, so check rate
    uint8_t delta = target - current;
    if ( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    //write current fan value for air control
    analogWrite(fan, (current + delta ));
    current = current + delta;
  }
}




Complete sketch:

#include <max6675.h>
#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[16] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1
};

/**
    Modbus object declaration
    u8id : node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI
                 or any pin number > 1 for RS-485
*/
Modbus slave(1, 0, 0); // this is slave @1 and RS-232 or USB-FTDI

// Pins for thermocouple MAX6675
int thermoDO = 6;
int thermoCS = 5;
int thermoCLK = 4;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

// declare variable for Arduino pin connected to solid state relay (SSR)
int relay = 9;

// declare variables for Arduino pins connected to fan controller (L293N)
int fan = 10; // ENA of L239N
int in1 = 11; // IN1 of L239N
int in2 = 12; // IN1 of L239N

// declare variables for Arduino pins to power MAX6675:
int vccPin = 3; // 5v power of MAX6675
int gndPin = 2; // gnd of MAX6675

// slew rate limitations for fan control
#define SLEW_STEP 10 // increase in steps of 10% for smooth transition
int target = 0;
int current = 0;

void slew_fan() { // limit fan speed increases
  target = ((au16data[5] / 100.0) * 255);
  if ( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if ( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    analogWrite(fan, (current - delta ));
    current = current - delta;
  }
  else if ( target > current ) { // ramping up, so check rate
    uint8_t delta = target - current;
    if ( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    //write current fan value for air control
    analogWrite(fan, (current + delta ));
    current = current + delta;
  }
}


void setup() {
  slave.begin( 19200); // 19200 baud, 8-bits, even, 1-bit stop
  // use Arduino pins
  pinMode(relay, OUTPUT);
  pinMode(fan, OUTPUT);
  //fan direction can be reversed by interchanging values for in1 and in2
  pinMode(in1, OUTPUT); digitalWrite(in1, HIGH);
  pinMode(in2, OUTPUT); digitalWrite(in2, LOW);

  pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);
  delay(500);
}

void loop() {
  //write current thermocouple value
  au16data[2] = ((uint16_t) thermocouple.readCelsius() * 100);

  //write current fan value for air control
  // analogWrite(fan, (au16data[5] / 100.0) * 255);
  slew_fan();

  //poll modbus registers
  slave.poll( au16data, 16 );

  // heater control:
  digitalWrite(relay, HIGH);
  delay(au16data[4] * 10);
  digitalWrite(relay, LOW);
  delay((100 - au16data[4]) * 10 - 1);
}
renatoa
Good find, congrats !

To have different timings for heater and fan, the main loop should be rewritten with significant changes.
A major point to rethink is the MAX library usage, which seems to be at least 250 ms of blocking code, that must be rewritten as async code, if you want total freedom.
zamunda
Hello Renatoa,

Thanks for your reply on the timings!

Quote

renatoa wrote:

To have different timings for heater and fan, the main loop should be rewritten with significant changes.
A major point to rethink is the MAX library usage, which seems to be at least 250 ms of blocking code, that must be rewritten as async code, if you want total freedom.


Based on what you state above, I made the following adjustments to the sketch...have to test it later but I would like to share the idea already. Does this make sense?

Big thanks as usual.


#include <max6675.h>
#include <ModbusRtu.h>

// Data array for modbus network sharing
uint16_t au16data[16] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1
};

/**
    Modbus object declaration
    u8id : node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI
                 or any pin number > 1 for RS-485
*/
Modbus slave(1, 0, 0); // this is slave @1 and RS-232 or USB-FTDI

/** Declare variables for Arduino pins connected for thermocouple MAX6675 */
int thermoDO = 6;
int thermoCS = 5;
int thermoCLK = 4;

/** Set up MAX6675 */
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

/** Declare variable for Arduino pin connected to solid state relay (SSR) */
int relay = 9;

/** Declare variables for Arduino pins connected to fan controller (L293N) */
int fan = 10; // ENA of L239N
int in1 = 11; // IN1 of L239N
int in2 = 12; // IN1 of L239N

/** Declare variables for Arduino pins to power MAX6675 */
int vccPin = 3; // 5v power of MAX6675
int gndPin = 2; // gnd of MAX6675

/** Slew rate limitations for fan control */
#define SLEW_STEP 10 // increase in steps of 10% for smooth transition
int target = 0;
int current = 0;

/** We have to cycle 3 events (temperature, fan, heater)  which need different timings */
const long eventTime_temperature = 300; //in ms
const long eventTime_fan = 1000; //in ms
const long eventTime_heater = 1000; //in ms

/** When did these events start */
unsigned long previousTime_1 = 0;
unsigned long previousTime_2 = 0;
unsigned long previousTime_3 = 0;

/** This is the slew_fan function */
void slew_fan() { // limit fan speed increases
  target = ((au16data[5] / 100.0) * 255);
  if ( target < current ) { // ramping down, so check rate
    uint8_t delta = current - target;
    if ( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    analogWrite(fan, (current - delta ));
    current = current - delta;
  }
  else if ( target > current ) { // ramping up, so check rate
    uint8_t delta = target - current;
    if ( delta > SLEW_STEP ) // limit the step size
      delta = SLEW_STEP;
    //write current fan value for air control
    analogWrite(fan, (current + delta ));
    current = current + delta;
  }
}

/** Set-up */
void setup() {
  slave.begin( 19200); // 19200 baud, 8-bits, even, 1-bit stop
  // use Arduino pins
  pinMode(relay, OUTPUT);
  pinMode(fan, OUTPUT);
  //fan direction can be reversed by interchanging values for in1 and in2
  pinMode(in1, OUTPUT); digitalWrite(in1, HIGH);
  pinMode(in2, OUTPUT); digitalWrite(in2, LOW);

  pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);
  delay(500);
}

/** Main loop */
void loop() {

  //** Poll modbus registers */
  slave.poll( au16data, 16 );

  /** Current time which updates frequently */
  unsigned long currentTime = millis();

  /** Three events with different timings */
  /** 1) Temperature event: write current thermocouple value */
  if ( currentTime - previousTime_1 >= eventTime_temperature) {
    au16data[2] = ((uint16_t) thermocouple.readCelsius() * 100);
  }

  /** 2) fan-event: write current fan value for air control */
  if ( currentTime - previousTime_2 >= eventTime_fan) {
    slew_fan();
  }

  /** 3) heater-event: heater control with SSR */
  if ( currentTime - previousTime_3 >= eventTime_heater) {
    digitalWrite(relay, HIGH);
    delay(au16data[4] * 10);
    digitalWrite(relay, LOW);
    delay((100 - au16data[4]) * 10 - 1);
  }

}


Reference: https://www.programmingelectronics.com/arduino-millis-multiple-things/
zamunda

Quote

renatoa wrote:

I see an issue in the heater loop area, that code will never give you more than 50% effective power into the heater element.
Also, the delay(5) statement is for 50 Hz mains, else the results will be random, if you mount a bulb instead heater you should see flickering.
I would replace this part:


// heater control loop:
for (int i = 1; i <= 99; i++) {
...
delay(500);


with...

digitalWrite(relay, HIGH);
delay(au16data[4] * 10);
digitalWrite(relay, LOW);
delay((100 - au16data[4]) * 10 - 1);


This change should give you full 0-100% range control, and not dependent on mains frequency.


Today I did some real roasting with the MODBUS setup where I controlled the heater from a Artisan slider and manual control for the fan. It went well though I noticed that when I set at a certain stage the heater to "100" temperature dropped severely during several seconds, once I set it to "90", temperature came back to normal.

When doing "dry-testing" of this setup with only a SSR and a fan connected to the Arduino, I also noticed that as soon I set the "heater" to 100, the fan stopped all of a sudden.

Looking at the heater-timing, I think the problem is caused by the value of "delay((100 - au16data[4]) * 10 - 1)", this becomes negative if slider (that is, value of au16data[4]) is set to 100. What I understand, this may result in very long delays.

So I changed this line to:
delay((100 - au16data[4]) * 10 + 1);
As a result, this delay is 1 millisecond when slider is set to 100.

I tested it and at least the fan stays on when I set heater slider to "100".

Is this a correct assumption and solution?

Please let me know.

Regards,



void loop() {
  //write current thermocouple value
  au16data[2] = ((uint16_t) thermocouple.readCelsius() * 100);

  //write current fan value for air control
  // analogWrite(fan, (au16data[5] / 100.0) * 255);
  slew_fan();

  //poll modbus registers
  slave.poll( au16data, 16 );

  // heater control:
  digitalWrite(relay, HIGH);
  delay(au16data[4] * 10);
  digitalWrite(relay, LOW);
  //delay((100 - au16data[4]) * 10 - 1);
  delay((100 - au16data[4]) * 10 + 1);

}

zamunda
Hello,

I am now ready to connect to the Arduino Board by BT, have the HC-06, from my Mac I can see the connection and can connect after putting the default pw (1234). But once connected it does not accept to upload my sketch from Arduino. Arduino is powered with a 1A adapter from my iPhone.

Do I miss something there?

From Artisan, I can configure the port to /dev/tty.HC-06-DevB/ but can not confirm that this works since I have no probe connected to the board yet.

I was wondering if there is something else needed to set up a succesfull connection from Mac/Artisan to the Arduino UNO?

Thanks in advance for any advice!

Regards
Edited by zamunda on 08/19/2021 12:58 PM
renatoa
You can't use the same serial comm port for both BT and USB.
Some switching is required, at least one of the lines.
Jump to Forum:

Similar Threads

Thread Forum Replies Last Post
TC4+ Arduino coffee roaster shield (TC4-compatible) Dataloggers/Controllers/Rate of Rise Meters 229 03/24/2021 11:30 AM
SOLVED: Artisan says: "Arduino could not set channels" Dataloggers/Controllers/Rate of Rise Meters 9 01/24/2021 2:14 AM
Arduino and Artisan Dataloggers/Controllers/Rate of Rise Meters 4 01/21/2021 1:07 PM
Ametek Motor -Speed Control / Arduino Control??? Fluidbed Roaster 29 11/05/2020 1:32 AM
Heater Protection via Arduino Fluidbed Roaster 5 09/21/2020 9:41 AM
Homeroasters Association Logo, and all Content, Images, and Icons © 2005-2016 Homeroasters Association - Logos are the property of their respective owners.
Powered by PHP-Fusion Copyright © 2021 PHP-Fusion Inc
Released as free software without warranties under GNU Affero GPL v3
Designed with by NetriX