二进制字符串在我的Arduino

时间:2018-01-11 13:08:55

标签: c++ arduino

我想将我存储的二进制字符串从两个中断(ISR_INT1,ISR_INT0)转换为十进制。我在Mac上使用gcc对此进行了测试,效果很好,给出了正确的小数。在我的Arduino上测试我得到一个完全不同的小数。我知道Arduino只能达到16位整数,所以我用了一个长而不是看下面的。非常感谢任何帮助或建议。

这是我的Arduino草图:

#define MAX_BITS 100               // max number of bits 
#define WEIGAND_WAIT_TIME  3000    // time to wait for another weigand pulse.  

unsigned char databits[MAX_BITS];  // stores all of the data bits
unsigned char bitCount;            // number of bits currently captured
unsigned char flagDone;            // goes low when data is currently being captured
unsigned int weigand_counter;      // countdown until we assume there are no more bits

unsigned long facilityCode = 0;    // decoded facility code
unsigned long cardCode = 0;        // decoded card code
String fullCard;                   // binary value full card number

int LED_GREEN = 11;
int LED_RED = 12;
int BEEP_BEEP = 10;

// interrupt that happens when INTO goes low (0 bit)
void ISR_INT0() {
  fullCard += 0;
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME;
}

// interrupt that happens when INT1 goes low (1 bit)
void ISR_INT1() {
  fullCard += 1;
  databits[bitCount] = 1;
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME;
}

void setup() {
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(BEEP_BEEP, OUTPUT);
  digitalWrite(LED_RED, HIGH); // High = Off
  digitalWrite(BEEP_BEEP, HIGH); // High = off
  digitalWrite(LED_GREEN, LOW);  // Low = On
  pinMode(2, INPUT); // DATA0 (INT0)
  pinMode(3, INPUT); // DATA1 (INT1)

  Serial.begin(9600);
  Serial.println("Snow RFID Reader PUT HID CARD ");

  // binds the ISR functions to the falling edge of INTO and INT1
  attachInterrupt(0, ISR_INT0, FALLING);
  attachInterrupt(1, ISR_INT1, FALLING);
  weigand_counter = WEIGAND_WAIT_TIME;
}

void loop() {
  // This waits to make sure that there have been no more data pulses before processing data
  if (!flagDone) {
    if (--weigand_counter == 0)
      flagDone = 1;
  }

  // if we have bits and we the weigand counter went out
  if (bitCount > 0 && flagDone) {
    unsigned char i;
    Serial.print(" ");
    Serial.print("Read ");
    Serial.print(bitCount);
    Serial.print(" bits. ");
    Serial.print(fullCard);

    **// THIS IS WHERE IT I TRY TO CONVERT MY BINARY STRING INTO A DECIMAL**

    long fullCardInt = bin2dec(const_cast<char*>(fullCard.c_str()));
    Serial.print(fullCardInt);
    if (bitCount == 35) {
      // 35 bit HID Corporate 1000 format
      // facility code = bits 2 to 14
      for (i = 2; i < 14; i++) {
        facilityCode <<= 1;
        facilityCode |= databits[i];
      }
      // card code = bits 15 to 34
      for (i = 14; i < 34; i++) {
        cardCode <<= 1;
        cardCode |= databits[i];
      }

      printBits();
    } else if (bitCount == 26) {
      // standard 26 bit format
      // facility code = bits 2 to 9
      for (i = 1; i < 9; i++) {
        facilityCode <<= 1;
        facilityCode |= databits[i];
      }

      // card code = bits 10 to 23
      for (i = 9; i < 25; i++) {
        cardCode <<= 1;
        cardCode |= databits[i];
      }
      printBits();
    } else {
      Serial.println("Unable to decode.");
    }

    // cleanup and get ready for the next card
    bitCount = 0;
    facilityCode = 0;
    cardCode = 0;
    for (i = 0; i < MAX_BITS; i++) {
      databits[i] = 0;
    }
  }
}

void printBits() {
  Serial.print("FC = ");
  Serial.print(facilityCode);
  Serial.print(", CC = ");
  Serial.println(cardCode);

  digitalWrite(LED_RED, LOW); // Red
  if (cardCode == 12345) {
    digitalWrite(LED_GREEN, HIGH);
  }
  delay(500);
  digitalWrite(LED_RED, HIGH);
  digitalWrite(LED_GREEN, LOW);
  digitalWrite(BEEP_BEEP, LOW);
  delay(500);
  digitalWrite(BEEP_BEEP, HIGH);
  delay(500);
  digitalWrite(BEEP_BEEP, LOW);
  delay(500);
  digitalWrite(BEEP_BEEP, HIGH);
}

long bin2dec(const char *bin) {
  int result = 0;
  for (; *bin; bin++) {
    if ((*bin != '0') && (*bin != '1'))
      return -1;
    result = result * 2 + (*bin - '0');
    //if(result<=0) return -1;
  }
  return result;
}

这是我的Arduino的串行终端读出来的

Snow RFID Reader PUT HID CARD 

 // bits read         Binary string          Incorrect decimal
 Read 26 bits.   00001000000100000101010011      16723             FC = 16, CC = 8361

这是我的Test.cpp脚本

//THIS WORKS AND GIVES ME THE CORRECT DECIMAL

#include <stdio.h>

int bin2dec(const char *bin) {
  int result=0;
  for(;*bin;bin++) {
    if((*bin!='0')&&(*bin!='1'))
      return -1;
    result=result*2+(*bin-'0');
  }
  return result;
}

int main (void) {
    printf("%d\n", bin2dec("00001000000100000101010011"));
    return(0);
}

这是我的测试cpp脚本给我的正确答案。

S:g$ g++ main.cpp -o SnowTest
S:g$ ./SnowTest 
2113875

1 个答案:

答案 0 :(得分:3)

正如你所说,Arduino上的int是16位。 在你的函数int bin2dec中,你返回intresult是一个int,所以在Arduino中你的数字被截断为16 lsb(100000101010011),在dec中是16723。 请改用long

long bin2dec(const char *bin)
{
  long result=0;
  for(;*bin;bin++)
  {
    if((*bin!='0')&&(*bin!='1'))
      return -1;
    result=result*2+(*bin-'0');
    //if(result<=0) return -1;
  }
  return result;
}