Pc and microcontroller rs232 communication error when 220v contactor switches

Thread Starter

Tinsae

Joined Jan 8, 2015
113
Dear all, I am doing a project in which pc and atmega32 communicate via rs232. The microcontroller send level signal and also receive command to actuate 220v contactor.
Every thing is fine until I connect the relays to drive the contactor I have checked electrical isolation between the board and the high volt, it is okay. The problem occur randomly when the contactor switch. When the problem occurs the microcontroller will not reset it still accept command from the pc but it will stop giving data to the pc through rs232. To solve this I tried to close and reopen the serial port programmatically when the issue occurs but the problem not solved the problem only goes away when I restarted the microcontroller. The source of the problem seems electromagnetic noise but I have done a microcontroller board which controls 220v loads without problem. The only difference here is the microcontroller communicate with computer and with one another microcontroller. Also tbe code is written with arduino ide with atmega plugins.
 

geekoftheweek

Joined Oct 6, 2013
1,201
Do you have any hardware flow control enabled on your serial port? Since it will still accept data from PC to mirco, but not the other way maybe the relays are causing some floating pin to change state (which it probably shouldn't do, but depends on what you are using). Other than that the only other thing maybe you are sending data at the same time the relays switch and you are missing a snubber somewhere that is messing with your micro (assuming mechanical relays).
 

Sensacell

Joined Jun 19, 2012
3,432
1) Reduce the generation of the interfering noise- snubbers, filters, timing etc.

2) Reduce the sensitivity to interfering noise - shielded cables, filters, grounding schemes etc.

Do both.
 

Thread Starter

Tinsae

Joined Jan 8, 2015
113
Part of the code
Full code of mcu and skematics attached


Dim WithEvents port As SerialPort = New _
System.IO.Ports.SerialPort("COM1", _
9600, _
Parity.None, _
8, _
StopBits.One)





Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

port.PortName = "COM1"
If Not port.IsOpen Then
port.Open()
End If

End Sub



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
port.Write((TextBox2.Text))
Thread.Sleep(20)
port.ReadTimeout = 13000
Thread.Sleep(1000)
TextBox1.Text = (port.ReadExisting)
Catch ex As TimeoutException
TextBox1.Text = "NoData"
MsgBox(ex.Message)
End Try
End Sub


the above is part of the code where the issue occurs
when ever i put the string ph02 at the text2 and click the button
the pc send this to the mcu and the mcu switch relay 02 and sendback the
string ph. This works fine as long as i left the contactor open. But when
i connect the relay to drive the contactor it switch on and off accordingly
but the mcu doesnt send back the string ph.

below is part of the mcu code where the problem occurs

void loop()
{

if (Serial.available())
{
inString = "";
inNum = "";
while (Serial.available() > 0)
{
int inChar = Serial.read();
inString += (char)inChar;
if (isDigit(inChar))
{
inNum += (char)inChar;
}
}
if (inString.charAt(0) == 'f' && inString.charAt(1) == 'l' && (inNum.toInt()) >= 0 && (inNum.toInt()) <= maxNumberOfTemperatureSensor)
{
Serial.flush();
digitalWrite(pumpIndex[inNum.toInt()], LOW);
}

if (inString.charAt(0) == 'r' && inString.charAt(1) == 't' && (inNum.toInt()) >= 0 && (inNum.toInt()) <= maxNumberOfTemperatureSensor)
{
Serial.flush();
Serial.end();
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
digitalWrite(pumpIndex[inNum.toInt()], LOW);
}


if (inString.charAt(0) == 'p' && (inNum.toInt()) > 0 && (inNum.toInt()) <= maxNumberOfPump) //computer send pump start command to the mcu
{
if (inString.charAt(1) == 'h')//if i use the above commented code then i should not use the if (serial.available()
{
digitalWrite(pumpIndex[inNum.toInt()], HIGH);
Serial.println("ph");
delay(100);
}
if (inString.charAt(1) == 'l') //if i use the above commented code then i should not use the if (serial.available()
{
digitalWrite(pumpIndex[inNum.toInt()], LOW);
Serial.println("pl");
delay(100);
}
}

}
delay(100);
}
 

Attachments

Thread Starter

Tinsae

Joined Jan 8, 2015
113
I believe prevention is better than cure. For my case already circuit is built and difficult to modify layout and add components even though adding snubber is easy at the contactor. But what about the cure at the code level because with all prevention noise could occur. As I told you when the problem occur still data from pc to mcu work but no the other way how to solve this? I have added code that close and open the serial port after switching the contactor but that doesn't solve
 

Attachments

MrChips

Joined Oct 2, 2009
30,711
I just seem to recall someone installing a software fix to correct a hardware problem. That didn't end up well. Just thinking.
 

Sensacell

Joined Jun 19, 2012
3,432
Looking at your board - it's lacking a ground plane.
This type of layout is notoriously hard to bulletproof - you will need to really focus on reducing the generation of noise.

Snubbers across the relay contacts and contactor contacts it a good start.
 

nerdegutta

Joined Dec 15, 2009
2,684
Hi.

I've noticed two things with the hardware:
1) Would it be better to have the capacitors on the other side of the crystal. Something like this:
Skjermbilde fra 2019-12-31 08-14-22.png

2) Would it be smart to have a diode across the terminals of the relay? Check out this Google search:
https://www.google.com/search?q=dio...UDxYsKHQ3ID3AQ_AUoAXoECAwQAw&biw=1215&bih=896

Your problems may not be solved with this, but at least your're a step closer to better hardware setup. Remember the words of a very wise man: "First comes the hardware - Then comes the software"
 

MrChips

Joined Oct 2, 2009
30,711
I only just noticed the perfboard construction. Sorry, that is not going to cut it.
Every piece of wire is an antenna for picking up interference. You have to go to a PCB with proper ground plane and preferably SMT devices, as @nerdegutta says. And make sure that you have proper power supply decoupling.
 

MrAl

Joined Jun 17, 2014
11,389
Hello,

If you can not solve it in hardware then you have to figure out what changes when the problem occurs and correct it somehow. For example, the EMI might cause an interrupt when it is not supposed to happen. You'd have to insert a piece of code into the interrupt routine to detect when it is triggered when it is not supposed to be triggered, then jump to where the execution really should be happening, or just return immediately.

This could also occur even when you DONT turn on some AC device with your circuit. For example, someone in the room turns on or off a fan. The EMI could couple into the circuit anyway even though the fan is not connected to the circuit in any way.
Interrupts on change are likely suspects but you'll have to figure this out perhaps by inserting some additional code that keeps track of where the execution is during the entire run.
The final solution though requires very careful testing to make sure nothing else goes wrong.
 

MaxHeadRoom

Joined Jul 18, 2013
28,617
The problem occur randomly when the contactor switch
For me, I would rather eliminate the source rather than allow it to exist and try an after the fact cure.
As previously stated, AC contactor coils are major source.
Max.
 

dendad

Joined Feb 20, 2016
4,451
As pointed out, your construction is not the best.
A few pointers that may help..
Each IC needs to have bypass caps as close as you can to the chip. I place then inside the sockets when building a proto like yours.
Keep all your leads short.
Opto isolate inputs and outputs where you can.
Use a balanced serial comms like RS485 instead of RS232.
Do not run comms leads close to other leads, and use shielded comms cables.
Often, troubling comms problems can be fixed by using isolated comms drivers.
These are pretty cheap and work well..
https://www.mornsun-power.com/html/product/Transceiver-Module.html
 

Thread Starter

Tinsae

Joined Jan 8, 2015
113
Dear nerdegutta there two 22pf cap for the crystal and free wheeling diode built in uln2003 ic.

I agree with all you about the poor circuit layout. But changing the hardware is difficult (except putting snubber in the contacror) due to time restriction so I prefere to know and fix effect of noise to the software as MrAI said noise generated interrupt and also unexpected restarting of the mcu with and without power on reset. For me if the the mcu restart any time I can handle where it was. But the current problem is the mcu, it still receive and switch on and off the contactor but dont send back confirmation. Is there any way for the mcu to restart without flushing its serial receiving buffer? By the way it is also recommend to include noise tolerant code for the best hardware
 

Thread Starter

Tinsae

Joined Jan 8, 2015
113
Dear all, execuse me if I insist on software solution please try to understand me. I have tried to solve with the help of watch dog timer. After switching the contactor (sending only pulse), I enabled wdt followed with infinite loop this way I was able to restart(I confirmed it restarted) the mcu but it still cant send data only receive. Then tried wdt interrupt in this routine I put
bitSet (MCUCSR,0) to make as the reset was power on reset but it doesnt help is there any way to default the serial out buffer
Serial.flush () has no effect
 

Sensacell

Joined Jun 19, 2012
3,432
It could well be that the UART is crashing in a non-recoverable way, requiring a power cycle to fully reset.
Noise glitches can cause MCU's to get into strange states internally that cannot be fixed by soft resets.

You aren't going to code your way out of this in any reliable way.
 

MrAl

Joined Jun 17, 2014
11,389
It could well be that the UART is crashing in a non-recoverable way, requiring a power cycle to fully reset.
Noise glitches can cause MCU's to get into strange states internally that cannot be fixed by soft resets.

You aren't going to code your way out of this in any reliable way.
Hi,

I've done it in the past but i was able to track down exactly what the program was doing and add some detection code. Worked well after that. But sure if there is another way then try that first.
 

MrAl

Joined Jun 17, 2014
11,389
Dear all, execuse me if I insist on software solution please try to understand me. I have tried to solve with the help of watch dog timer. After switching the contactor (sending only pulse), I enabled wdt followed with infinite loop this way I was able to restart(I confirmed it restarted) the mcu but it still cant send data only receive. Then tried wdt interrupt in this routine I put
bitSet (MCUCSR,0) to make as the reset was power on reset but it doesnt help is there any way to default the serial out buffer
Serial.flush () has no effect
Hello,

Are you saying that you reset the uC after you switch the contactor? Isnt it too late then?
Why dont you try using the wdt before you switch the contactor? If the wdt remains true to its cause then you may be able to reset the uC properly. It sounds like the reset doesnt work after you switch the contactor for some reason.

Is it possible that you might be able to discover what the uC does when the contactor switches? In my case i traced the problem to an interrupt that was happening due to the EMI noise and so was able to use some code inside the inerrupt routine to detect if it really was an interrupt i intended or was triggered by something else (the noise). That solution was fairly easy.
The key point is that the contactor must be causing the uC to do something it was not supposed to do. It could be changing the program flow (as in my case) or it could be flipping one or more register bits that work the peripheral(s).
So you need to discover what is changing first, otherwise you may never find a solution.
 
Top