Bit and byte and udp

Hi everyone,

This is another bit / byte / hex question.
I’m not a very skilled programmer but i’m trying to learn and this is the first time i propose myself to manipulate bits so i am kind of lost.
I have a node js script sending udp info to a uno via ethernet. It’s working as i’m receiving strings and casting it to int, and it works fine. The thing is that i think i’m not optimizing correctly something that should be easy. And i also will have to figure out the node part to send the correct byte or bit or whatever is needed, but here is the arduino deal:

I just need to set 4 relays on or off according to the received udp message.
I think it could be acheivable on a single byte received, but since i’m using string the packet lenght i think is 4 bytes currently. And my idea is to make the udp packet as short as possible. I guess i could use just one byte because from that 8 bits i only need 4 of them, one for each relay.
I could use direct port manipulation for setting pin2(relay1), pin3(relay2), pin5(relay3) and pin6(relay4) with the bit operators that i don’t master but would try to learn but for now i would like to know how could i “parse” or cast some hex value so that i could set each digitalwrite(relaypins) to bit(0) until bit(3) value.

Can someone shed me a light on the correct way to do this, please? I hope i made myself clear.

Thank you!

Can someone shed me a light on the correct way to do this, please?

Send a single byte (NOT a String or string) with bits 0 to 3 set to the value you want to output
Put the output pin numbers in an array
Then

for (int bit = 0; bit < 4; bit++)
{
  digitalWrite(pinArray[bit], bitRead(theByte, bit));
}

Hi!! Thank you so much for the help! Will try this asap. Bitread. I was thinking i had to use the bit(). I am not sure of it’s use but i will try!

UKHeliBob:
Send a single byte (NOT a String or string) with bits 0 to 3 set to the value you want to output
Put the output pin numbers in an array
Then

for (int bit = 0; bit < 4; bit++)

{
  digitalWrite(pinArray[bit], bitRead(theByte, bit));
}

Yeah…so… this is not working out right because i’m clueless. I can’t manage to get hold of the byte on udp.

    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    byte theByte = int(packetBuffer[1]);
    Serial.println(theByte,BIN);

    for (int bit = 0; bit < 4; bit++)
    {
      digitalWrite(pinArray[bit], bitRead(theByte, bit));
      
    }

clearly not getting it. packetBuffer is char [24] and i don’t know how to cast this.

Why do you think your data byte is in the second location of the packet buffer? Why do you cast it to an int, when it is immediately implicitly cast to a byte?

for (int bit = 0; bit < 4; bit++)
    {
      digitalWrite(pinArray[bit], bitRead(packetBuffer[0], bit));
    }

I’ve got it! Thank you!

@aarg … because i’m like that dog meme… i have no idea of what i am doing!

I assume that you did not add those color tags, but I would be interested to know where you copied the code from and how you copied it, as I would like to get to the bottom of why color tags are sometimes added when copying code

BTW - it's good news that you got it working

Yeah that can be a pain! I’ve copied from visual studio code. If i paste it here on the reply button color tag appears. But if i edit the post after and paste it again it just appears as plain text. Don’t know why...

I got it working but from trial and error because i still dont exactly get this conversions as getting to have just a byte on the udp read was also not easy and i have a lot to dig until i understand how i can make a char in a array become just a hex. The node part was even harder as i needed to make a string that i had that was like “0010” to convert to hex and i only managed to make that happen by manually adding “0x” to it at the beggining and then i parseInt(var,2).toString(16) so i could use Buffer.from(parsedintvar, “hex”) and it was ok. What a mess in my mind....

And then i needed to reverse my LSB order because the first bit was reading on the last relay but i got lazy and just reversed the pin order because i feel like i will not know how to make it in a simple order. I feel like making the arduino for iteration for bit counter going from 4 to 0 is a was but there should be a easier way

I've copied from visual studio code. If i paste it here on the reply button color tag appears. But if i edit the post after and paste it again it just appears as plain text. Don't know why...

Thanks for the details but I cannot reproduce the problem

The description of your solution to the UDP/byte problem is vey convoluted. Whilst I admit to knowing nothing about UDP data transmission it surely should not be necessary to use Strings, hex or an int just to transmit and receive a byte

Where is the UDP data coming from ?

I’m on mac and catalina, don’t know if it can have anything to do with the color thing.

The source is code i made.
On node you can send udp packets as easily as putting a string , port and ip and it’s done. But if you feed it a string it will make (hope i’m not wrong) an hex for each char in the string, which is normal. But for sending 0000 bits i was having a packet lenght of 4 and i wanted it to be just 1. Because one hex could accomplish every relay situation i needed. Kind of like a shift register. That’s “my problem”. As i’m sending a lot of packets (every each 70ms) for different destinations i would like them to be as lean as possible. Checked on wireshark and the size of each udp packet reduced 1/3.
Which might not even impact the wifi network that much but it gives me some peace of mind. I’m learning and don’t have an idea of what it can or can’t mess up a wifi router.

if you feed it a string it will make (hope i'm not wrong) an hex for each char in the string,

Hex is for humans to make reading and understanding data easier. Computers work quite happily in bits an bytes, so I doubt that hex comes into it anywhere

Yeah i understand what you are saying. Maybe i expressed myself incorrectly. What i meant is that it’s not a hex by itself , its a byte, but on the transmission wireshark detects packet lenght of 4 so each char is a byte represented by a hex value. It’s a way for displaying data.

I have been experimenting with UDP

The best that I came up with was

Client code

  static byte aByte = 0;
  static char buffer[10];
  itoa(aByte++, buffer, 10);  //increment byte value for test
  udp.broadcastTo(buffer, 1234);

Server code

      char buffer[20];
      memcpy(buffer, packet.data(), packet.length());
      buffer[packet.length()] = '\0'; //turn buffer into a string
      byte aByte = atoi(buffer);  //convert to a byte
      Serial.println(aByte, BIN);  //print byte in binary

There may well be a way to simply send a byte, but this works and may be similar to the method that you employed

@UkHeliBob

Will try your example for fun as i’ve managed some other way i’m not remembering now. Didn’t notice your reply until now but thank you so much for your very usefull help! Really. Thank you.
Regards