user23787: I am using Controllino Maxi. It has an Arduino Uno inside it. I am trying to control the PWM pin D0 and digital pin R0 via python code. Below is the code I have upload on arduino:
Arduino Code:
#include <Ethernet.h> 
#include <EthernetUdp.h> 
#include <SPI.h> 
#include <Controllino.h>

byte mac[] ={}; 
IPAddress ip(192, 168, 0, 200); 
unsigned int localPort = 5000; 
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; 
String datReq; 
int packetSize; 
EthernetUDP Udp; 

void setup() 
{
  Ethernet.begin( mac, ip); 
  Udp.begin(localPort); //Initialize Udp
  pinMode(CONTROLLINO_D0, OUTPUT);
  pinMode(CONTROLLINO_R0, OUTPUT);

}

void loop() {
  packetSize =Udp.parsePacket(); //Reads the packet size
  if(packetSize>0) 
  {
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
    String datReq(packetBuffer);
    if (datReq == "R0") 
    {
      digitalWrite(CONTROLLINO_R0, HIGH);
      delay(2000);
      digitalWrite(CONTROLLINO_R0, LOW);
    }
    else 
    {
      analogWrite(CONTROLLINO_D0, datReq.toInt());
      delay(2000);
      analogWrite(CONTROLLINO_D0, 0);
    }
  }
 }

In above code, if I receive R0 over ethernet, then I am turning on/off R0 pin, else whatever PWM I am receiving, I am setting it using analogWrite. Below is my python code:
from socket import *
import time

address = ('192.168.0.200', 5000)  # define server IP and port ((0x12, 0x02, 0x00, 0x00, 0xEA, 0x03))
client_socket = socket(AF_INET, SOCK_DGRAM)  # Set up the Socket
client_socket.settimeout(1)

data = "R0".encode("utf-8")  
client_socket.sendto(data, address)  
time.sleep(5)

data = ("{}".format(200)).encode("utf-8")  
client_socket.sendto(data, address)  
time.sleep(5)

data = ("{}".format("R0")).encode("utf-8")  
client_socket.sendto(data, address)  

In above code, I am first sending R0 to turn on/off R0 and then sending 200 for PWM and then again sending R0 to turn on/off R0. When tested I can see R0 getting high and low, then I can see 200 on PWM but then again R0 should be high/low but it stays low. If  I re run the python code, R0 doesnt work and only PWM works. If I power off the board and power it again, then R0 works only for first time and it didnt work in second time.
I am a bit confused at this stage. Is there any bug in my arduino code as I am not very experienced in it. Is there any way to debug it? Please help. THanks

user7508: You Arduino sketch is storing the received UDP packet in a char array
named packetBuffer, then converting this array to a String object
like this:
String datReq(packetBuffer);

The problem is that this String constructor expects a NUL-terminated
array, and you have no guarantee that this array is NUL-terminated.
Well, actually you have this guarantee, but only at the beginning: as
the program starts, the array will be filled with zeros by the C
initialization routine. This is why the first request is correctly
processed. The second request sends a packet larger than the first one,
so the array is still NUL-terminated. On the third request, however, the
received bytes are immediately followed by the leftovers of the previous
request. In this case it is the digit '0'.
The simple solution is to ensure that the buffer is always properly
terminated. Start by making it wider by one byte:
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // +1 for the '\0'

Then, whenever you receive a packet, add the terminating NUL character:
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
packetBuffer[packetSize] = '\0'; // properly terminate the buffer


23787: <p>I am using <a href="https://www.controllino.com/product/controllino-maxi/" rel="nofollow noreferrer">Controllino Maxi</a>. It has an Arduino Uno inside it. I am trying to control the PWM pin <code>D0</code> and digital pin <code>R0</code> via <code>python</code> code. Below is the code I have upload on arduino:</p>
<p><code>Arduino Code</code>:</p>
<pre><code>#include &lt;Ethernet.h&gt; 
#include &lt;EthernetUdp.h&gt; 
#include &lt;SPI.h&gt; 
#include &lt;Controllino.h&gt;

byte mac[] ={}; 
IPAddress ip(192, 168, 0, 200); 
unsigned int localPort = 5000; 
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; 
String datReq; 
int packetSize; 
EthernetUDP Udp; 

void setup() 
{
  Ethernet.begin( mac, ip); 
  Udp.begin(localPort); //Initialize Udp
  pinMode(CONTROLLINO_D0, OUTPUT);
  pinMode(CONTROLLINO_R0, OUTPUT);

}

void loop() {
  packetSize =Udp.parsePacket(); //Reads the packet size
  if(packetSize&gt;0) 
  {
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
    String datReq(packetBuffer);
    if (datReq == &quot;R0&quot;) 
    {
      digitalWrite(CONTROLLINO_R0, HIGH);
      delay(2000);
      digitalWrite(CONTROLLINO_R0, LOW);
    }
    else 
    {
      analogWrite(CONTROLLINO_D0, datReq.toInt());
      delay(2000);
      analogWrite(CONTROLLINO_D0, 0);
    }
  }
 }
</code></pre>
<p>In above code, if I receive <code>R0</code> over ethernet, then I am turning on/off <code>R0</code> pin, else whatever PWM I am receiving, I am setting it using <code>analogWrite</code>. Below is my <code>python</code> code:</p>
<pre><code>from socket import *
import time

address = ('192.168.0.200', 5000)  # define server IP and port ((0x12, 0x02, 0x00, 0x00, 0xEA, 0x03))
client_socket = socket(AF_INET, SOCK_DGRAM)  # Set up the Socket
client_socket.settimeout(1)

data = &quot;R0&quot;.encode(&quot;utf-8&quot;)  
client_socket.sendto(data, address)  
time.sleep(5)

data = (&quot;{}&quot;.format(200)).encode(&quot;utf-8&quot;)  
client_socket.sendto(data, address)  
time.sleep(5)

data = (&quot;{}&quot;.format(&quot;R0&quot;)).encode(&quot;utf-8&quot;)  
client_socket.sendto(data, address)  
</code></pre>
<p>In above code, I am first sending <code>R0</code> to turn on/off <code>R0</code> and then sending <code>200</code> for PWM and then again sending <code>R0</code> to turn on/off <code>R0</code>. When tested I can see <code>R0</code> getting high and low, then I can see <code>200</code> on PWM but then again <code>R0</code> should be high/low but it stays low. If  I re run the python code, <code>R0</code> doesnt work and only PWM works. If I power off the board and power it again, then <code>R0</code> works only for first time and it didnt work in second time.</p>
<p>I am a bit confused at this stage. Is there any bug in my arduino code as I am not very experienced in it. Is there any way to debug it? Please help. THanks</p>
 7508: <p>You Arduino sketch is storing the received UDP packet in a <code>char</code> array
named <code>packetBuffer</code>, then converting this array to a <code>String</code> object
like this:</p>
<pre class="lang-cpp prettyprint-override"><code>String datReq(packetBuffer);
</code></pre>
<p>The problem is that this <code>String</code> constructor expects a NUL-terminated
array, and you have no guarantee that this array is NUL-terminated.</p>
<p>Well, actually you have this guarantee, but only at the beginning: as
the program starts, the array will be filled with zeros by the C
initialization routine. This is why the first request is correctly
processed. The second request sends a packet larger than the first one,
so the array is still NUL-terminated. On the third request, however, the
received bytes are immediately followed by the leftovers of the previous
request. In this case it is the digit <code>'0'</code>.</p>
<p>The simple solution is to ensure that the buffer is always properly
terminated. Start by making it wider by one byte:</p>
<pre class="lang-cpp prettyprint-override"><code>char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // +1 for the '\0'
</code></pre>
<p>Then, whenever you receive a packet, add the terminating NUL character:</p>
<pre class="lang-cpp prettyprint-override"><code>Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
packetBuffer[packetSize] = '\0'; // properly terminate the buffer
</code></pre>
