JT007
February 9, 2014, 11:01am
1
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
system
February 9, 2014, 11:38am
2
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
JT007
February 9, 2014, 12:06pm
4
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.
system
February 9, 2014, 12:09pm
5
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
Robin2
February 9, 2014, 12:30pm
7
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
JT007
February 9, 2014, 12:31pm
8
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