Go Down

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

AJITnayak

Apr 18, 2018, 06:55 pm
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

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

#1
Apr 18, 2018, 07:26 pm
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

#2
Apr 19, 2018, 10:52 am
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

#3
Apr 19, 2018, 11:49 am
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 pmLast 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

#5
Apr 19, 2018, 05:22 pm
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

#6
Apr 20, 2018, 03:10 am
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
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

#7
Apr 20, 2018, 03:28 amLast 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

#8
Apr 20, 2018, 04:09 am
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.
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

#9
Apr 20, 2018, 05:35 am
Ok. How can save the bitvalue  to form byte. I need sample code for it. to move the  values to

Next Byte
and so on
AMPS

GoForSmoke

#10
Apr 20, 2018, 10:47 am
Next Byte
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
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

#11
Apr 22, 2018, 12:13 pm
iS THERE ANY EXAMPLE DOING IT. i GONE THROUGH LIBRARY BUT NEVER IMPLIMENT FOR READ COIL. dO U HAVE SUGGESTION FOR IT
AMPS

GoForSmoke

#12
Apr 22, 2018, 06:08 pm
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.