Pages: [1]   Go Down
Author Topic: Concatenate from buffer  (Read 270 times)
0 Members and 1 Guest are viewing this topic.
Lake District, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Electronics needs smoke to work, if it escapes its broken
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

Quote
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.

Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

so buffer60Bytes holds something like

Code:
'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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Lake District, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Electronics needs smoke to work, if it escapes its broken
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
serial.print (buffer60Bytes);
You've provided no proof that the array is properly NULL terminated OR that it contains characters.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

UK
Offline Offline
Faraday Member
**
Karma: 101
Posts: 6201
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Lake District, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Electronics needs smoke to work, if it escapes its broken
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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();
        
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

 
Code:
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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Pages: [1]   Go Up
Jump to: