Python Forum
How to convert 4 bytes to an integer ?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to convert 4 bytes to an integer ?
#1
Hi, I am using SPI on Raspberry Pi (master) and collecting 4 bytes at a time. I need to convert this back to integer. How can I do it?
When I do it using struct...it gives some random garbage values:
        b=spi.readbytes(4)
        value=struct.unpack("<I", bytearray(b))[0]
        print (value)
Thanks.
Reply
#2
Depends on the order they need to be converted.

Do you have an example of the bytes that you receive and know the specific integer that it should form? Your code seems reasonable for converting a set of bytes in little-endian format. Big-endian would need a ">I" format.

>>> struct.unpack("<I", bytes([35, 0, 0, 0]))
(35,)
Reply
#3
(Jan-17-2022, 12:06 AM)bowlofred Wrote: Do you have an example of the bytes that you receive and know the specific integer that it should form?

Thanks for the reply. Yes, I need to convert it to little endian. On the slave side, I have for ex. 4094 as a 32bit integer. I convert it to 4 8-bit integers as below and then send it over to RP:
          b1 = (unsigned int)(data_adc & 0xff); //data_adc is 32 bit integer
          b2 = (unsigned int)(data_adc >> 8) & 0xff;
          b3 = (unsigned int)(data_adc >> 16) & 0xff;
          b4 = (unsigned int)(data_adc >> 24);

          int testarray[4]={b1,b2,b3,b4};

          for (int i = 0; i < 4; i++){
                        USART_SpiTransfer(USART0, testarray[i]); 
          }
So basically, when this data_adc is always 4094, the slave always sends [254,15,0,0] (checked using debugger on slave side). So, I should receive the same on Raspberry Pi.

In fact when I change the print statement to:
print (b)


I get this:
.
.
[15L, 224L, 0L, 0L]
[0L, 0L, 253L, 224L]
.
.
And these 2 lines are repeating instead of only repeating [254,15,0,0]. Any suggestion, what I might be doing wrong here?
Reply
#4
Sounds like your struct conversion is working, but there is a problem with the actual data transfer. Maybe one side or the other is not interpreting the data as a byte. Can you just test that you can send and receive a sequence of octets properly?

Your output looks like you're using python2. I'd hope you could use python 3 instead.
Reply
#5
(Jan-17-2022, 01:35 AM)bowlofred Wrote: Sounds like your struct conversion is working, but there is a problem with the actual data transfer. Maybe one side or the other is not interpreting the data as a byte. Can you just test that you can send and receive a sequence of octets properly?

Your output looks like you're using python2. I'd hope you could use python 3 instead.

I have a question, by octets do you mean those 8 bytes that I am receiving? If so, why?
Because I am only sending 4 data bytes together, then why are we considering octets? Please correct me if I am not thinking this correctly.

And okay, I will use python 3.
Reply
#6
I used python 3 to execute the code.

This time instead of sending [255,15,0,0] from slave, I am sending [0,0,15,255] and on RP, I receive data as
.
.
[0,0,15,255]
[255,255,0,0]
.
.
This works but it doesn't makes sense, why. Also, IDK why this second set of 8-bit integers is very different from what I expect.
Reply
#7
I too am using python 3 with the following, for the test I used a list and filled it with the four byte values you have been transmitting. It works with a RS232 transmission also.

b=[254,15,0,0]
  value = int.from_bytes(b, byteorder='little', signed=False)    
  print(value)  


which prints 4094
Reply
#8
Hi Jeff_t,

After I changed the order of the bytes being sent from the slave side "....This time instead of sending [255,15,0,0] from slave, I am sending [0,0,15,255] and on RP, I receive data as....", I also received 4094 by using the struct method too.

But as @bowlofred mentioned, it seems like there is some problem in the data transfer...I also feel the same because I am receiving one set of 4 bytes of data as expected and the next set is very different. Instead, they all should be same and should be equal to 4094 after conversion.

I am trying to figure out what might be the problem, but until now no luck.
Reply
#9
Can you show the code on the sending and receiving side that transfers the data?

Re: "octet", no that's just a group of 8 bits. Some people prefer that to "byte" because not all bytes (especially historically) were 8 bits in width.
GiggsB likes this post
Reply
#10
(Jan-17-2022, 03:44 AM)bowlofred Wrote: Can you show the code on the sending and receiving side that transfers the data?

This is on slave side (just adding snippet related to SPI, because its a very long code):
//data transfer variables
uint32_t data_adc;
uint8_t b1,b2,b3,b4;

// Configure MOSI pin as an input
  GPIO_PinModeSet(US0MOSI_PORT, US0MOSI_PIN, gpioModeInput, 0);

  // Configure MISO pin as an output
  GPIO_PinModeSet(US0MISO_PORT, US0MISO_PIN, gpioModePushPull, 0);

  // Configure CLK pin as an input
  GPIO_PinModeSet(US0CLK_PORT, US0CLK_PIN, gpioModeInput, 0);

  // Configure CS pin as an input pulled high
  GPIO_PinModeSet(US0CS_PORT, US0CS_PIN, gpioModeInput, 1);

void initUSART0(void){
//not adding code snippet but these are the setting:
1. set as slave
2. speed: 4000000
3. MSB transferred first
4. 8 data bits
5. clock mode 0
}
while(1){
.
.
USART_SpiTransfer(USART0, 'S'); /* this function performs one 8-bit frame SPI transfer. 
This function will stall if the transmit buffer is full. When a transmit buffer becomes available, data is written and the function will wait until data is fully transmitted. The SPI return value is then read out and
 returned. */

      for(uint32_t i = 0; i < 98; i++){
          data_adc = *((uint32_t *)StartPage+i); //data read from flash memory

          b1 = (unsigned int)(data_adc & 0xff);
          b2 = (unsigned int)(data_adc >> 8) & 0xff;
          b3 = (unsigned int)(data_adc >> 16) & 0xff;
          b4 = (unsigned int)(data_adc >> 24);

          int testarray[4]={b4,b3,b2,b1};

          for (int i = 0; i < 4; i++){
                        USART_SpiTransfer(USART0, testarray[i]); //no new line character??
                    }
      }
      USART_SpiTransfer(USART0, 'D'); //'D' will be sent as an integer!! To tell RP, all data has been transferred.
.
.
}
Below is code on master side (Raspberry Pi):
# spi.py
import time
import spidev
import array as arr
import struct

# We only have SPI bus 0 available to us on the Pi
bus = 0

#Device is the chip select pin. Set to 0 or 1, depending on the connections
device = 0

# Enable SPI
spi = spidev.SpiDev()

# Open a connection to a specific bus and device (chip select pin)
spi.open(bus, device)

# Set SPI speed and mode
spi.max_speed_hz = 4000000
spi.mode = 0

print("Enter '1' to start the process")
a=input()
if a:
    print("SM1 Process started...")
    spi.xfer2([0x01])
    
    while True:
        #spi.xfer2([0,0,0,0])
        b=spi.readbytes(4)
        value=struct.unpack("<I", bytearray(b))[0]
        print (value)
     
else: 
    print("Wrong input.")
One thing, I didn't add in the slave code is that: when the slave is powered on, master sends a command, '1' to slave and slave checks if it receives '1'. If it receives '1' then this whole above process is started. So that much communication is happening correctly.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Help with implementation of the logic to convert roman numeral to integer jagasrik 2 2,318 Aug-14-2020, 07:31 PM
Last Post: deanhystad
  Pack integer values as single bytes in a struct bhdschmidt 3 2,340 Jun-09-2020, 09:23 PM
Last Post: bhdschmidt
  convert from csv row to 16 bit bytes adetheheat 1 1,652 Feb-28-2020, 03:04 PM
Last Post: Larz60+
  8-bit integer to bytes Garitron 1 3,002 Sep-14-2019, 11:22 PM
Last Post: ichabod801
  replace bytes with other byte or bytes BigOldArt 1 10,631 Feb-02-2019, 11:00 PM
Last Post: snippsat
Question [Help] Convert integer to Roman numerals? {Screenshot attached} vanicci 10 9,184 Aug-06-2018, 05:19 PM
Last Post: vanicci
  Convert integer to string Maigol 5 5,536 Mar-05-2018, 10:25 PM
Last Post: python_master89
  cannot convert float infinity to integer error despite rounding off floats Afterdarkreader 3 15,224 Dec-15-2017, 02:01 AM
Last Post: micseydel
  How to convert character to integer in python rajeev1729 2 3,852 Oct-03-2017, 04:30 PM
Last Post: nilamo
  Logic to convert an integer to YEAR / MONTH hugobaur 9 7,924 Oct-18-2016, 11:58 AM
Last Post: hugobaur

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020