Concatenate from buffer

im wanting to get values from a buffer and convert them to decimal values.

im working on A model train DCC decoder and the code im trying to manipulate is as follows

char buffer60Bytes[60];
i have discovered i can write out the contents

Serial.print (buffer60Bytes[9]);//command 3F
Serial.print (buffer60Bytes[10]);
Serial.print (buffer60Bytes[11]);
Serial.print (buffer60Bytes[12]);
Serial.print (buffer60Bytes[13]);
Serial.print (buffer60Bytes[14]);
Serial.print (buffer60Bytes[15]);
Serial.print (buffer60Bytes[16]);
Serial.print (" ");

but it looks like each bin in the buffer contains an ascii character
so 00111111 in this case 3F is 8 ascii characters long.

i think the reason the coder has done it this way is because the pulses 1 & 0 are clocked in serially

so if i wanted to obtain a decimal value result from these 8 bits how might i do it

the first four blocks of 8 are of interest to me (buffer60Bytes[0]); to (buffer60Bytes[32]);
as they contain the locomotive DCC data

they come out as 11001010 00111111 00100000 11110101
which translates to
40 the address of the train
3F the command
** the speed and direction
and an Xor checksum
apparently although ive not proven this yet either

so in short, i have a buffer and i want to add the content of so many bins together to make a decimal value
any help would be much appreciated

for refference
http://www.mynabay.com/arduino/2-uncategorised/14-arduino-dcc-monitor

the sketch is the monitor example in the download. just in case anyone is interested

i think the reason the coder has done it this way is because the pulses 1 & 0 are clocked in serially

But, we don't need to see that code.

so if i wanted to obtain a decimal value result from these 8 bits how might i do it

The simplest is to investigate bitSet(). If the nth value is '1', set the nth bit. If the nth value is '0', do nothing.

so buffer60Bytes holds something like

'1','1','0','1','1','0','1','1','0'

etc? IE ASCII ones and zeros, but you want a single binary value for each 8 characters?


Rob

Hi Rob,
Yes im looking to get a decimal value from binary of the ascii 1s and 0s.

i did try reading each value and adding is value to the power of 2 to an int variable.
i have tried joining the characters to make a string containing 8 characters and was then hoping to convert that to a decimal value
neither of which were successful.

when i tried to print out each buffer bin using a for loop i got nothing when i printed the count it was working fine, just the count did not translate to the buffer bin
ie
for i =0,i=7, i++
serial.print (buffer60Bytes*);*
i know i should stick to engineering but Arduinos as so addictive.

i did try reading each value and adding is value to the power of 2 to an int variable.

Some code?

serial.print (buffer60Bytes);

You've provided no proof that the array is properly NULL terminated OR that it contains characters.

Assuming the array does contain the data as said and that the order is B7 to B0, this code should create a byte from the first 8 characters

byte b = 0;

for (int i = 0; i < 8; i++) {
	b <<= 1;
	b |= buffer60Bytes[i] == '1' ? 1 : 0;
}

Try that, and if it works add more to step through the array and do them all.


Rob

The array buffer60Bytes[60] is defined as an array of characters - that's what the "char" at the start of the line means.

Converting 8 characters - such as 00111111 - into a binary value (not decimal!) requires you to raise each digit position to a higher power of two. So, working from right to left (least significant bit to most significant bit) the maths will be like this

1 * 2 ^ 0 +
1 * 2 ^ 1 +
1 * 2 ^ 2 +
1 * 2 ^ 3 +
1 * 2 ^ 4 +
1 * 2 ^ 5 +
0 * 2 ^ 6 +
0 * 2 ^ 7

This is what @Graynomad's code does, although it does it in a slightly different way. With binary data << (shift left) is the same as multiplying by 2, but much faster.

...R

Thanks Rob
works a treat

look at void DumpAndResetTable() for your input


Just to keep pointless Paul happy here is the code

[code#]
include <DCC_Decoder.h>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Defines and structures
//
#define kDCC_INTERRUPT            0
 int count;
    byte validBytes;
    byte data[6];
    
typedef struct
{
    int count;
    byte validBytes;
    byte data[6];
} DCCPacket;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// The dcc decoder object and global data
//
int gPacketCount = 0;
int gIdlePacketCount = 0;
int gLongestPreamble = 0;

DCCPacket gPackets[25];

static unsigned long lastMillis = millis();
    
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Packet handlers
//

// ALL packets are sent to the RawPacket handler. Returning true indicates that packet was handled. DCC library starts watching for 
// next preamble. Returning false and library continue parsing packet and finds another handler to call.
boolean RawPacket_Handler(byte byteCount, byte* packetBytes)
{
        // Bump global packet count
    ++gPacketCount;
    
    int thisPreamble = DCC.LastPreambleBitCount();
    if( thisPreamble > gLongestPreamble )
    {
        gLongestPreamble = thisPreamble;
    }
    
        // Walk table and look for a matching packet
    for( int i=0; i<(int)(sizeof(gPackets)/sizeof(gPackets[0])); ++i )
    {
        if( gPackets[i].validBytes )
        {
                // Not an empty slot. Does this slot match this packet? If so, bump count.
            if( gPackets[i].validBytes==byteCount )
            {
                char isPacket = true;
                for( int j=0; j<byteCount; j++)
                {
                    if( gPackets[i].data[j] != packetBytes[j] )
                    {
                        isPacket = false;
                        break;
                    } 
                }
                if( isPacket )
                {
                   gPackets[i].count++;
                   
                  
                   return false;
                }
            }
        }else{
                // Empty slot, just copy over data
            gPackets[i].count++;
            gPackets[i].validBytes = byteCount;
            for( int j=0; j<byteCount; j++)
            {
                gPackets[i].data[j] = packetBytes[j];
                
                 
            }
            return false;
        }
    }    
    
    return false;
}

// Idle packets are sent here (unless handled in rawpacket handler). 
void IdlePacket_Handler(byte byteCount, byte* packetBytes)
{
    ++gIdlePacketCount;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Setup
//
void setup() 
{ 
   Serial.begin(9600);
    
   DCC.SetRawPacketHandler(RawPacket_Handler);   
   DCC.SetIdlePacketHandler(IdlePacket_Handler);
            
   DCC.SetupMonitor( kDCC_INTERRUPT );   
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void DumpAndResetTable()
{
    char buffer60Bytes[60];
    
    byte b = 0;

for (int i = 0; i < 8; i++) {
	b <<= 1;
	b |= buffer60Bytes[i] == '1' ? 1 : 0;
}

  Serial.print (b);
  Serial.print (" ");  
  
  
       Serial.print (buffer60Bytes[0]);//addresss
       Serial.print (buffer60Bytes[1]);
       Serial.print (buffer60Bytes[2]);
       Serial.print (buffer60Bytes[3]);
       Serial.print (buffer60Bytes[4]);
       Serial.print (buffer60Bytes[5]);
       Serial.print (buffer60Bytes[6]);
       Serial.print (buffer60Bytes[7]);
       Serial.print (" ");
       
       
       Serial.print (buffer60Bytes[9]);//command 3F
       Serial.print (buffer60Bytes[10]);
       Serial.print (buffer60Bytes[11]);
       Serial.print (buffer60Bytes[12]);
       Serial.print (buffer60Bytes[13]);
       Serial.print (buffer60Bytes[14]);
       Serial.print (buffer60Bytes[15]);
       Serial.print (buffer60Bytes[16]);
       Serial.print (" ");
       
       Serial.print (buffer60Bytes[18]);//Dir and speed
       Serial.print (buffer60Bytes[19]);
       Serial.print (buffer60Bytes[20]);
       Serial.print (buffer60Bytes[21]);
       Serial.print (buffer60Bytes[22]);
       Serial.print (buffer60Bytes[23]);
       Serial.print (buffer60Bytes[24]);
       Serial.print (buffer60Bytes[25]);
       Serial.print (" ");
       
       Serial.print (buffer60Bytes[27]);//XOR
       Serial.print (buffer60Bytes[28]);
       Serial.print (buffer60Bytes[29]);
       Serial.print (buffer60Bytes[30]);
       Serial.print (buffer60Bytes[31]);
       Serial.print (buffer60Bytes[32]);
       Serial.print (buffer60Bytes[33]);
       Serial.println (buffer60Bytes[34]);
    
    Serial.print("Total Packet Count: ");
    Serial.println(gPacketCount, DEC);
    
    Serial.print("Idle Packet Count:  ");
    Serial.println(gIdlePacketCount, DEC);
        
    Serial.print("Longest Preamble:  ");
    Serial.println(gLongestPreamble, DEC);
       
    Serial.println("Count    Packet_Data");
    for( int i=0; i<(int)(sizeof(gPackets)/sizeof(gPackets[0])); ++i )
    {
        if( gPackets[i].validBytes > 0 )
        {
            Serial.print(gPackets[i].count, DEC);
            if( gPackets[i].count < 10 )
            {
                Serial.print("        ");
            }else{
                if( gPackets[i].count < 100 )
                {
                    Serial.print("       ");
                }else{
                    Serial.print("      ");
                }
                

                
            }
            Serial.println( DCC.MakePacketString(buffer60Bytes, gPackets[i].validBytes, &gPackets[i].data[0]) );
            

            
            
        }
        gPackets[i].validBytes = 0;
        gPackets[i].count = 0;
    }
    Serial.println("============================================");
    
    gPacketCount = 0;
    gIdlePacketCount = 0;
    gLongestPreamble = 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Main loop
//
void loop()
{
    DCC.loop();
    
    if( millis()-lastMillis > 2000 )
    {
        DumpAndResetTable();
        lastMillis = millis();
        
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

First you could get rid of the 30+ Serial.print()s with something like

for (int x = 0; x < 4, x++) {   // crap variable names, but it's late :)
  	  for (int y = 0; y < 8, y++) {
 		Serial.print (buffer60Bytes[(x * 8) + y]);
	  }
       Serial.print (" ");    
  }

Rob