Serial Communication Problem - Simulink/Arduino

Dear all,

I am having some trouble with my masters project, studying multivariable controllers. I am using Serial to send data from 2 sensors to Simulink, solve the control law and give back signals to my actuators.

Sensors: LDR and LM35
Actuators: rotation of a PC fan and voltage of a lamp.

My problem is specifically with the lamp. I am having something which looks like interference from serial, making my lamp to flicker. The lamp is connected in AC and I use zero cross detection (opto) to know where to cut the wave and then a TRIAC to send the a DelayMicroseconds to the lamp.

As I use Simulink to perform my controllers calculations, I have to send 2 numbers to Simulink and receive 2 as well, every second.

P.S.1: Using only a simple code to turn on the lamp for a specific "powertime" works fine. I tested all the components of my circuit
P.S.2: Even running just the Arduino Code without running the Simulink Model, I also have this flickering problem.
P.S.3: When I enable the interrupts it seems the problem stops, but I really need them to perform all the loops every second. Probably there is a more elegant way to perform such tasks.

CODE 1: Just to turn on the lamp for a given "powertime". Works perfectly.

#include <DueTimer.h>

#define zeroPin 2                                                     
#define outputPin 3

int i; 
float powertime;
                                                  

void setup() {
  Serial.begin(57600);
  pinMode(zeroPin, INPUT);                                            
  pinMode(outputPin, OUTPUT);                                    
  while(true){
    if (digitalRead(zeroPin) == HIGH){
    zeroCross();
    }  
  }
}

void zeroCross()  {
  powertime = 5000;                                                   
  delayMicroseconds(powertime);                                       
  digitalWrite(outputPin,HIGH);                                     
  delayMicroseconds(15);                                              
  digitalWrite(outputPin,LOW);
  }

void loop(){
}

CODE 2: A code I´ve developed to communicate using serial. I receive the data from Simulink and give it back. Also it works perfectly.

char strToSend[128];                                
double ddataBuff, ddataBuff1, ddataBuff2;          
String Buff, cBuff,dBuff;                          
char Buff1[128], Buff2[128];                        
int n;                                              
int posfinal[2], posD;

void setup() {
  Serial.begin(57600);                              
}

void loop() {
  while (Serial.available() > 0) {               
    Buff = Serial.readStringUntil('\n');          
  }
  posD=0;
  posfinal[0] = Buff.indexOf(32,posD);
  posD = posfinal[0]+1;
  posfinal[1] = Buff.indexOf(0,posD);
  posD = posfinal[1];
  for(n = 0; n < posfinal[0]; ++n){               
    Buff1[n] = Buff[n];
  }
  Buff1[127] = '\0';                             
  for(n = 0; n < posfinal[1]; ++n){               
    Buff2[n] = Buff[posfinal[0] + 1 + n];
  }
  Buff2[127] = '\0';                              
  ddataBuff1 = atof(Buff1);                       
  ddataBuff2 = atof(Buff2);                       
  ddataBuff = ddataBuff1 + ddataBuff2;                         
  cBuff = String(ddataBuff,DEC); 
  dBuff = cBuff;
  dBuff.toCharArray(strToSend,8);
  Serial.println(strToSend);
  for( n = 0; n < sizeof(Buff1);  ++n ){
      Buff1[n] = (char)0;
  }
  for( n = 0; n < sizeof(Buff2);  ++n ){
      Buff2[n] = (char)0;
  }
}

CODE 3: My complete code that does not work and make the lamp to flicker.

#include <DueTimer.h>


#define zeroPin 2
#define dimmerPin 3
#define fanPin 11
#define ldrPin A0
#define lm35Pin A2
#define ledPin 13

char strToSend1[128], strToSend2[128], finalString[128];  
volatile double ddataBuff1, ddataBuff2;                
String Buff, c1Buff, c2Buff, d1Buff, d2Buff;             
char Buff1[128], Buff2[128];                              
int n;                                                    
int posfinal[2], posD;
volatile double powerlamp0, powerfan0;             
volatile int powerlamp1, powerfan1, powertime;      
int cont1, cont2;  
double tempAux1[50],tempAux2, tempReal;
double lumAux1[50], lumAux2, lumReal;
int ledState = 0;

void setup() {  
  Serial.begin(57600);                              
  pinMode(zeroPin,INPUT);                           
  pinMode(dimmerPin,OUTPUT);                        
  pinMode(fanPin,OUTPUT);                           
  pinMode(ledPin,OUTPUT);  
  Timer3.attachInterrupt(matlab);                   
  Timer3.start(1000000);                            
  Timer4.attachInterrupt(send_data);
  Timer4.start(1000000);
  Timer5.attachInterrupt(receive_data);
  Timer5.start(1000000);
  while (true) {                                    
    if (digitalRead(zeroPin) == HIGH){              
      zeroCross();                                                                 
    }
    digitalWrite(ledPin,ledState);
  }
}

void matlab() {                                    
  powerlamp0 = ddataBuff1;
  powerfan0 = ddataBuff2;
  powerlamp1 = (int)powerlamp0;
  powerfan1 = (int)powerfan0; 
  analogWrite(fanPin,powerfan1); 
  ledState = !ledState;
}


void receive_data() {
    while (Serial.available() > 0) {             
        Buff = Serial.readStringUntil('\n');       
      }  
    posD=0;                                        
    posfinal[0] = Buff.indexOf(32,posD);            
    posD = posfinal[0]+1;                           
    posfinal[1] = Buff.indexOf(0,posD);            
    posD = posfinal[1];
    for(n = 0; n < posfinal[0]; ++n){              
      Buff1[n] = Buff[n];
    }
    Buff1[127] = '\0';                             
    for(n = 0; n < posfinal[1]; ++n){              
      Buff2[n] = Buff[posfinal[0] + 1 + n];
    }
    Buff2[127] = '\0';                              
    ddataBuff1 = atof(Buff1);                      
    ddataBuff2 = atof(Buff2);                       
    for( n = 0; n < sizeof(Buff1);  ++n ){         
      Buff1[n] = (char)0;
    }
    for( n = 0; n < sizeof(Buff2);  ++n ){          
      Buff2[n] = (char)0;
    } 
}
 
void send_data() { 
  tempAux2 = 0;
  tempReal = 0;
  lumAux2 = 0;
  lumReal = 0;
  for (cont1 = 0; cont1 < 50;cont1++) {
    tempAux1[cont1] = analogRead(lm35Pin); 
    tempAux2 = tempAux2 + tempAux1[cont1];
  }
  tempReal = tempAux2 / 50;
  for (cont2 = 0; cont2 < 50;cont2++) {
    lumAux1[cont2] = analogRead(ldrPin); 
    lumAux2 = lumAux2 + lumAux1[cont2];
  }
  lumReal = lumAux2 / 50;
  c1Buff = String(lumReal,DEC);                 
  c2Buff = String(tempReal,DEC);                 
  d1Buff = c1Buff;
  d2Buff = c2Buff;
  d1Buff.toCharArray(strToSend1,8);                
  d2Buff.toCharArray(strToSend2,8);                
  sprintf(finalString,"%s %s",strToSend1,strToSend2);  
  Serial.println(finalString);                      
}

void zeroCross()  {                                   
  powertime = powerlamp1;                           
  delayMicroseconds(powertime); 
  digitalWrite(dimmerPin, HIGH);   
  delayMicroseconds(15);
  digitalWrite(dimmerPin, LOW);  
}

void loop() {                                      
}

UPDATE: I was testing my code and when I remove just the "analogWrite" line, it works just perfectly! I repeated this test several times to make sure it wasn´t just a coincidence. I have no idea why the "analogWrite" is causing this interference though.

In CODE 1, the part while(true) {…} should be inside loop() eventually without a while(true).

In Code 3, you NEVER call matlab(), receive-data(), send-data().

https://www.arduino.cc/en/Reference/Loop/

And why are you using Serial.begin(57600), very slow, whereas you can use Serial.begin(250000) ?

First of all thank you for your comments.

I've previously tried all your suggestions, but it also didn't work. I need the interrupts to perform those blocks every second. If I use "delay" inside the loop, I lose the lamp reference and it starts to blink.

I also tried to change baud rate but it has no effect on the flickering (from 9600 to 115200).

As I said, without the "analogWrite" everything is working just perfect. I don't know what kind of interference it is causing in the whole program. Now I'll try change the PWM programming.

tdquadros:
I need the interrupts to perform those blocks every second. If I use "delay" inside the loop, I lose the lamp reference and it starts to blink.

Since every 1 second is super slow, you had better using millis() (and not delay, see blink without delay, this is a non blocking code), you definitely don't need a timer trigger for that.

What frequency do you need for the PWM pulse ?

tdquadros:
I need the interrupts to perform those blocks every second. If I use "delay" inside the loop, I lose the lamp reference and it starts to blink.

Since every 1 second is super slow, you had better using millis() (and not delay, see blink without delay, this is a non blocking code), you definitely don't need a timer trigger for that.

What frequency do you need for the PWM pulse ?

Edison, I didn't think about millis().

Regarding the resolution, I need something between 80 and 250 (8 bit resolution). This is one of my controlled variables. It must change the value based on the control law every second.

tdquadros:
I need something between 80 and 250 (8 bit resolution). This is one of my controlled variables. It must change the value based on the control law every second.

That is not the PWM frequency but (part of) the duty cycle.

To select a different frequency, you had better using PWM library or TC library from antodom or make some direct register programming with the PWM peripheral or the timer counter peripheral.

SOLVED

It turned out my problem was not in the code, but I selected the wrong transistor for my fan. I have no idea why, but the transistor (BD139) from the fan circuit was causing interference in the lamp circuit, although the only physical connection between them was the common ground.

I changed from the BD139 to a TIP122 and no more flickering.