Go Down

Topic: bit storing as byte (Read 286 times) previous topic - next topic

AJITnayak

i am looking for sample code where , length is 50 bits  these bits are stored in byte format. Is there any sample code avialble here.


If i am sending first order address:0000
second order address :0031

length of bits will be 49 bits. I would like to store them in byte format 8 bit of each

8 bits are digital status of the digital IOS . How can i store them 
AMPS

UKHeliBob

To store 49 (or 50) bits of data you need to use 8 bytes
An array of 8 bytes and use of the bitWrite() function would enable you to do what you want.

A small amount of maths would allow you to calculate which bit in which byte holds the data for a specified bit out of 49 (or 50)

How are you receiving the data to be stored ?

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

AJITnayak

I have Input will pass argument

First will be address : 0001
 second will be no of bits to be read :0032

My data should read from 01 address to 50 bit of data.

I have length of bits to be read  32.
 total no of byte = 32/8 = 6 byte

I would like to store as below. where bits represent digital status of digital pins either 0 or 1


Code: [Select]

Byte_Addr[0]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}
Byte_Addr[1]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}
Byte_Addr[2]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}
Byte_Addr[3]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}
Byte_Addr[4]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}
Byte_Addr[5]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}



I need simple code to store these bits values to form byte and pack them properly .
if request is from 01 to no of data same data only should print,

AMPS

UKHeliBob

50 bits ?
32 bits ?

Which is it ?

Try this
Code: [Select]

byte dataArray[] = {0, 0, 0, 0, 0, 0, 0, 0};
byte setThisBit = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println();
  showBits();
  setABit(0, 1);
  showBits();
  setABit(1, 1);
  showBits();
  setABit(1, 0);
  showBits();
  setABit(20, 1);
  showBits();
 
}

void loop()
{
}

void showBits()
{
  for (int theBytes = 0; theBytes < 8; theBytes++)
  {
    for (int theBits = 0; theBits < 8; theBits++)
    {
      Serial.print(bitRead(dataArray[theBytes], theBits));
      Serial.print(" ");
    }
    Serial.println();
  }
}

void setABit(byte bitToSet, byte bitValue)
{
  byte theByte = bitToSet / 8;
  Serial.print("byte : ");
  Serial.println(theByte);
  byte theBit = bitToSet % 8;
  Serial.print("bit : ");
  Serial.println(theBit);
  bitWrite(dataArray[theByte], theBit, bitValue);
}


Does it do any of what you want ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

AJITnayak

#4
Apr 19, 2018, 05:11 pm Last Edit: Apr 19, 2018, 05:18 pm by AJITnayak
I am trying to impilment modbus RTU with read coil register.

http://dghcorp.com/modbus/modbusrtu01.asp
 

I have working code till receive data upto crc check &  receive response from slave.  My main problem is once data being received how can read coil register & pack data & send back for CRC check

I havent used the serial of arduino i have written in embedded c on atmega controller.


Code: [Select]
unsigned int crc_fn(unsigned char *dpacket,unsigned int len)    // CRC Function(Error calcualtion)
{
     unsigned int crc = 0xffff,poly = 0xa001;
     unsigned int i=0;
               
     for(i=0;i<len;i++)
     {
        crc^= dpacket[i];
        for(j=0;j<8;j++)
        {
              if(crc & 0x01)
              {
                   crc >>= 1;
                   crc ^= poly;
              }
              else
                     crc >>= 1;
        }
     }
     return (crc);     
}




Code: [Select]

void serial_Request()
{
     unsigned int address,crc1,crc2;
     unsigned char length,i,j=0; 
     
    // Serial_1_Send_byte(rxbuf[0]);
    crc2=crc_fn(&rxbuf[0],6);      //crc function for received protocol from request
     __delay_ms(10); // Changed on 20.01.2017
    if((rxbuf[6]==(unsigned char)(crc2))&&(rxbuf[7]==((unsigned char)(crc2>>8))))
    {
               
           if(rxbuf[0]==Device_ID)
           {
           
            //Serial_1_Send_byte(rxbuf[0]);
           
                if(rxbuf[1]==READ_REG)
                {
                     address=(((unsigned int)(rxbuf[2]<<8))+((unsigned int)(rxbuf[3])));
                     if(rxbuf[5]>=1)
                     {
                           length=(rxbuf[5]*2);
                           address=(address*2);
                           ser_data[0]=METER_ID;
                           ser_data[1]=rxbuf[1];
                           ser_data[2]=length;
                           ser_data[3]=00;// Put higher byte address Here
                           ser_data[4]=01;// Put Lower  byte address Here
                           ser_data[5]=00;
                           ser_data[6]=04;
                         
                   
                   
                           crc_data[0]=Device_ID;
                           crc_data[1]=rxbuf[1];
                           crc_data[2]=length;
                           j=3;
                           for(i=address;i<((address+length));i++)
                          {
                                crc_data[j++]=ser_data[i+3];
                           }
                           crc1 =crc_fn(&crc_data[0],(length+3)); //crc function for response protocol from the device

                           Serial_1_Send_byte(ser_data[0]);
                           Serial_1_Send_byte(rxbuf[1]);
                           Serial_1_Send_byte(ser_data[2]);
                   
                           for(i=address;i<((address+length));i++)
                           {
                                Serial_1_Send_byte(ser_data[i+3]);
                       
                           }
                           Serial_1_Send_byte((unsigned char)crc1);
                           Serial_1_Send_byte((unsigned char)(crc1>>8));
                   
                    /* line add for slow down*/
                   
                    for(i=0;i<30;i++)
                    {
                       Serial_1_Send_byte(0);
                    }
                   
                     }
                }     
            __delay_ms(5);
       }
           
     }
    index=0;
     rec_flag = 0;
   
     
}




Its working code for function 3 , Now i would like modify for function 1 .as attached in link

request goes in 01 01 00 00 00 31 fd de
rxbuf[0]= 01 //device Id always
rxbuf[1]= 01 //Functional code
rxbuf[2]= 00 //higher byte of start address
rxbuf[3]= 00 //Lower byte of start address
rxbuf[4]= 00 //HI Number of Bits
rxbuf[5]= 31 //LO Number of Bits
rxbuf[6]= FD //CRC1
rxbuf[7]= DE //CRC2

Upto here coming properly. 
I need to modify my address & length accordingly so accordingly  i need to store digital status coil based on length & pack it send with crc check response. but i dont know can i store bits of my digital io pins.

AMPS

UKHeliBob

AMPS - as usual with your queries I have no idea what you are talking about. 

Can you please explain in English, not with a program, what your current problem is ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

AJITnayak

I have code written for function 3 modbus RTU , Now i Need to modify code for function1

difference between bits and byte store. function3 uses byte store & function1 use bit store. Now in above code  i am getting input request from master coming well.

I.e request goes in 01 01 00 00 00 31 fd de

  based on request  i need to send response back. where
rxbuf[2]= 00 //higher byte of start address
rxbuf[3]= 00 //Lower byte of start address
rxbuf[4]= 00 //HI Number of Bits
rxbuf[5]= 31 //LO Number of Bits
data to be read from starting address
 0 to 31 bit address. I am facing problem in



1) calculate length & address  of length.

 
Code: [Select]

This for function 3, need length calculation for bits
 length=(rxbuf[5]*2);
   address=(address*2);


2) Storing  bits values in array_data[]


Code: [Select]

Byte_Addr[0]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}
Byte_Addr[1]={bit9,bit10,bit11,bit12,bit13,bit14,bit15,bit16}
Byte_Addr[2]={bit17,bit18,bit19,bit20,bit21,bit22,bit23,bit24}




3)Once data store . pack the Data & send for CRC check

Code: [Select]

crc_data[0]=Device_ID;
                           crc_data[1]=rxbuf[1];
                           crc_data[2]=length;
                           j=3;
                           for(i=address;i<((address+length));i++)
                          {
                                crc_data[j++]=ser_data[i+3];
                           }
                           crc1 =crc_fn(&crc_data[0],(length+3)); //crc function for response protocol from the device




AMPS

adwsystems

#7
Apr 20, 2018, 03:28 am Last Edit: Apr 22, 2018, 01:58 pm by adwsystems
I am trying to impilment modbus RTU with read coil register.

http://dghcorp.com/modbus/modbusrtu01.asp
 

I have working code till receive data upto crc check &  receive response from slave.  My main problem is once data being received how can read coil register & pack data & send back for CRC check

I havent used the serial of arduino i have written in embedded c on atmega controller.
What do you find lacking in any of the existing libraries for Modbus RTU?

GoForSmoke

You read and send bytes on the bus?
It is a serial bus as well, no?

So you don't need a 49 bits long bit string especially when you have 24 bits of address in that data. Just send bytes without converting to bits first. If you need to construct a single byte to hold 2 or more values, use bitwise logic to shift, mask and set bits or use C bit fields.

Simple fact is that your code should have all the message bytes in the output buffer before the first byte has completed sending. If not, it should rather soon.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

AJITnayak

Ok. How can save the bitvalue  to form byte. I need sample code for it. to move the  values to

Byte_Addr[0]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}
Next Byte
Byte_Addr[1]={bit9,bit10,bit11,bit12,bit13,bit14,bit15,bit16}
and so on
AMPS

GoForSmoke

Byte_Addr[0]={bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8}
Next Byte
Byte_Addr[1]={bit9,bit10,bit11,bit12,bit13,bit14,bit15,bit16}
and so on

Yes, look, each byte IS 8 bits but from high order to low: (like 256 is 2x100+5x10+6x1, high to low left to right).

byte value = bit7x2^7, bit6x2^6, bit5x2^5, bit4x2^4, bit3x2^3, bit2x2^2, bit1x2^1, bit0x2*0.... 2*0 = 1 if bit is set.

You can manipulate bits in a byte or other integer variable using the Arduino bit commands to set or clear any bit by number.
You can shift bits in an integer places to the right (divides by powers of 2) or left (multiplies by 2's) and write bits into the cleared positions.

But you never have to break down what you send to all bits. 24-bit addresses are best calculated in 32-bit unsigned long and then, love this part, you take the address of the unsigned long and the first 3 bytes ARE the 24-bit address in low to high byte order, that is how unsigned long is stored on Arduino.

There is no need to figure out the individual bits for that 24 bits.

 This Arduino Playground link can get you versed in bit math. Then you may see things differently.

https://playground.arduino.cc/Code/BitMath
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

AJITnayak

iS THERE ANY EXAMPLE DOING IT. i GONE THROUGH LIBRARY BUT NEVER IMPLIMENT FOR READ COIL. dO U HAVE SUGGESTION FOR IT
AMPS

GoForSmoke

I can point out what I see from you. I can suggest some troubleshooting but you don't want to do that.

I didn't pick your project and I don't care to become a modbus expert just for you.

I don't have your answer and now I am through trying to help.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

Go Up