uint64_t data type implementation

Hi All,

Can anyone help, I need to datatype that is at least 2^38 bits to be able to cope with RFID FDX_B tag serial number.
I though I found it by using unit64_t and including the sdtint.h library from avr, however it turn out to be only a long datatype. I have casted to int8_t for the purpose of printing to the terminal.
Here is my test sketch(edited Blink):

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
#include "stdint.h"
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;
uint64_t time1= 4294967295;  // this is a long type ie 32 bits long not 64!.
int8_t time2= 39;

// the setup routine runs once when you press reset:
void setup() {   
   Serial.begin(9600);   
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);  
  Serial.println(int8_t(time1)); 
  Serial.println(time2);   
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

Hi,

danomahoney:
I need to datatype that is at least 2^38 bits to be able to cope with RFID FDX_B tag serial number.

Do you plan to perform arithmetic on the serial number?

I need to datatype that is at least 2^38 bits

Hmmm.... 34GB+ that's a hell of storage space that you need :wink:

:slight_smile:

"unsigned long long" is a 64 bit type.
I'm not sure why uint64 should be considered a 32 bit type.

Edit:

void setup ()
{
  uint64_t time1; 
  Serial.begin (9600);
  Serial.println (sizeof (time1));  
}

void loop ()
{
  
}

prints the single digit 8.

Hi All,

Yes, I need to do a crc on a block of data which is 8 bytes, this is made up of 5 fields, a serial number for the tag which is 38 bits, a country code 10 bits, 2 more bits which define the application, and addition data presence and the rest, 14 bits always set to zero.

I don't need to do the crc very fast as I can post-process after capature, I have seen some assembler code for the crc and implementing the datatype but its difficult to follow and I don't know how to include assembler code in the arduino.

There must be an easier way than resorting to assembler, any ideas?

I know there is a limit switch during complie something like -mint8 but do not see during compile or up load.
Here is the header file and the spec for the FDXB:
http://www.nongnu.org/avr-libc/user-manual/stdint_8h_source.html

Am I missing somthing?

All the best Dan

I think if you could find a

uint16_t crc16(byte[] data)

function, that would solve your problem.

I guess C implementations of such functions can be found on the web, that can be just copy-n-pasted into your code.

my 2 cents.

danomahoney:
I though I found it by using unit64_t and including the sdtint.h library from avr, however it turn out to be only a long datatype. I have casted to int8_t for the purpose of printing to the terminal.

I found the same thing. "uint64_t" is actually a "long" (and not even unsigned!)

I found the same thing. "uint64_t" is actually a "long" (and not even unsigned!)

Interesting assertion.

uint64_t x = 0x0123456789abcdefULL;

void setup ()
{
  Serial.begin (9600);
  unsigned long y = x >> 32;
  unsigned long z = x & 0xffffffff;
  Serial.println (y, HEX);
  Serial.println (z, HEX);
}

void loop ()
{
}

Care to comment?

danomahoney:
Yes, I need to do a crc on a block of data...

Which? There are an infinite varieties of "CRC".

A Ha, Thankyou AWOL,

Adding ULL at the end makes it work, I presume it stands for unsigned long long.

All the best Dan

Hi Coding Badly,

The crc implemented in FDXB is reversed CCITT with a ploy. of $8408 initialised to $0000, I can't use crc16.h because it's only for a 16 bit data block and its initialised to $FFFF.

All the best Dan

danomahoney:
I can't use crc16.h because it's only for a 16 bit data block and its initialised to $FFFF.

All three of those claims are false. You can use the functions in crc16.h to calculate a CRC over 64 bits of data. You feed data to the functions 8 bits at a time not 16 bits. You are responsible for the initial value so you can easily set it to zero.

It's just unsigned long long:

From: <install_dir>\arduino-1.0.1\hardware\tools\avr\avr\include\stdint.h

typedef unsigned long long int uint64_t;

As the others said, the CRC routines are designed to be done a byte at a time. You don't think RFID readers do 64-bit arithmetic?

Just a warning, if you look at generated code if you do happen to use "long long" type, it generates very very lengthy code. As an example, AWOL's sketch above uses roughly 300 bytes of program memory more than the same sketch done with "int" type.

Thankyou both Nick and Coding Badly,

I shall try to implement crc16.h as you say and report back in a day or so.

All the best Dan

Hi All,
Following on from the above implementation problem, some people pointed out that I can used crc16.h, I have thus tried to implement this, but I can't seem to get it to work here is my sketch and some real tag data:

#include <util\crc16.h>

uint16_t testCrc;
uint16_t initalSet;

//byte FDXBData[] = {0x80, 0x00, 0xf1, 0xc0, 0x00, 0x8e, 0x94, 0xac};
//byte FDXBData[] = {0x35, 0x29, 0x71, 0x00, 0x03, 0x8f, 0x00, 0x01}; // reversed ie littlend lsb first, id# 000009344172, country code 967 crc should be 0x4FEB
byte FDXBData[] = {0x80, 0x00, 0x00, 0x00, 0x03, 0x9f, 0x00, 0x01};  // reversed  crc should be 0x2E44, id# 000000000001, country code 999

void setup ()
{
  Serial.begin (9600);
  
  initalSet = 0x0000;
  testCrc = FDXB_CRC16(initalSet, FDXBData);
  Serial.println (testCrc, HEX);
}

void loop ()
{
}


uint16_t FDXB_CRC16(uint16_t crc, byte* FDXBData)
{
    uint8_t i, c;
  
    for (i = 0; i < 8; i++)
    {
      c = FDXBData[i];
      Serial.print (crc, HEX);
      Serial.print (" : ");
      crc = _crc_ccitt_update(crc, c);  // reversed CCITT poly 0x8408
      Serial.print (i);
      Serial.print (" : ");
      Serial.print (c, HEX);
      Serial.print (" : ");
      Serial.println (crc, HEX);
    }   
    return crc;
}

I have been looking at post from someone with a simular problem and tried the working solution but it does not work in this case above. I have alo tried sevarl on line java script crc calculators but get different reults from each.

Any clues, let know if I should start a new thread.

ATB Dan

BTY the other thread or topic was by Criomod, titled CRC-CCITT Not returning valid...

What is the ouput of that sketch ?

Also, could you provide the link to crc16.h you're using ? I'd like to try it out. Thank you ! :slight_smile:

Hi Tuxduino,
The output is:

0 : 0 : 80 : 8408
8408 : 1 : 0 : 8CCC
8CCC : 2 : 0 : CEC
CEC : 3 : 0 : 2D6E
2D6E : 4 : 3 : B8CE
B8CE : 5 : 9F : 43B4
43B4 : 6 : 0 : F3EC
F3EC : 7 : 1 : 3C18
3C18

and the link is : avr-libc: <util/crc16.h>: CRC Computations

ATB Dan

Thanks for the link. I'll try a test sketch ASAP. Meanwhile...

but I can't seem to get it to work here is my sketch and some real tag data

what is the problem with the output you posted ? Is the CRC wrong ?

Here's my test sketch:

// crc16 calculation test
//
// Instruction:
// - upload
// - open serial monitor at 115200
// - set line termination cr lf
// - send a string
// - read the crc16 value
// - check the result here:
// http://www.lammertbies.nl/comm/info/crc-calculation.html

#include <util/crc16.h>

const char CR = 13;
const char LF = 10;
const byte BUFSIZE = 100;
char buffer[BUFSIZE];
byte bufCnt = 0;

void processBuffer(const char* buf) {
    int len = strlen(buf);
    
    if (len == 0) {
        Serial.println("Buffer is empty.");
    }
    
    uint16_t crc = 0;
    for (int i = 0; i < len; i++) {
        crc = _crc16_update(crc, buf[i]);
    }
    
    Serial.print("String=");
    Serial.println(buffer);
    Serial.print("crc16=");
    Serial.println(crc, HEX);
}

void processChar(char ch) {
    if (ch == CR || ch == LF) {
        if (bufCnt > 0) {
            buffer[bufCnt] = 0;
            processBuffer(buffer);
            bufCnt = 0;
        }
    }
    else {
        if (bufCnt < BUFSIZE - 1) {
            buffer[bufCnt] = ch;
            bufCnt++;
        }
    }
}

void setup() {
    Serial.begin(115200);
}

void loop() {
    if (Serial.available()) {
        processChar(Serial.read());
    }
}