I'm trying to build an Arduino based RFID emulator. I found this project that uses an AVR to do exactly what I want http://www.alexanderguthmann.de/en/emulator.html . From what I understand I need to generate a 125KHz wave with that uses amplitude modulation to transmit the data (which is manchester encoded). So, as a real beginner with this stuff, I have some pretty basic questions.
- Can I generate the sine wave by turning the pin off and on at the correct rate (125KHz)?
- If that's how I do it, how to I emulate amplitude modulation?
From what I understand from his C code, he's using one of the built in timers and messing with the amplitude based on if the bit is a one or a 0. Here's what looks like a relevant C code (and some non-relevant serial stuff).
#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <compat/ina90.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <avr/sleep.h>
#include <inttypes.h>
#ifndef F_CPU
#define F_CPU 8000000UL // Systemtakt in Hz - Definition als unsigned long beachten >> Ohne ergeben Fehler in der Berechnung
#endif
#define BAUD 9600UL // Baudrate
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif
/* Zusaetzlich zur Baudrateneinstellung und der weiteren Initialisierung: */
uint8_t getc()
{
while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar
{
}
return UDR;
}
unsigned char zeichen,z1,z2,z3;
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
volatile int bit_counter=0;
volatile int byte_counter=0;
volatile int half=0;
#define ZEILEN 5
#define SPALTEN 8
unsigned char card_ID[ZEILEN][SPALTEN] = //Die ID des zu emulierenden
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, //RFID tags
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};
unsigned char data[8];
void delay_ms(int ms) { // 1.000 MHz
int m;
for (m=0; m < ms; m++) {
TCNT0=0;
while (TCNT0 < 125);
}
}
ISR(SIG_OUTPUT_COMPARE1A){
TCNT1=0;
if (((data[byte_counter] << bit_counter)&0x80)==0x00) {
if (half==0) cbi(PORTB,PB1);
if (half==1) sbi(PORTB,PB1);
}
else {
if (half==0) sbi(PORTB,PB1);
if (half==1) cbi(PORTB,PB1);
}
half++;
if (half==2) {
half=0;
bit_counter++;
if (bit_counter==8) {
bit_counter=0;
byte_counter=(byte_counter+1)%8;
}
}
}
int main(void)
{
int k;
DDRB=0xFF;
DDRD=0x00;
PORTC=0x00;
DDRC = 0xff;
UCSRB |= (1<<TXEN); // UART TX einschalten
UCSRC |= (1<<URSEL)|(3<<UCSZ0); // Asynchron 8N1
UCSRB |= ( 1 << RXEN );
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
int i, j, l, u;
z1 = 0xFF;
i = 0;
j = 0;
u = 0;
while (1)
{
z3 = getc();
if(z3 == 0x73) //Warten bis ASCII S auf der seriellen schnittstelle liegt
{
while (1)
{
z1 = getc();
// z1 = 0x43;
if (z1 == 0x65) //65 = ASCII E E = Exit
{
break; //Schleife verlassen
}
if (j == 8) {
j = 0;
i++;
}
card_ID[i][j] = z1;
j++;
u = 1;
}
}
if (u == 1)
{
break;
}
}
PORTC ^= ( 1 << PC0 ); //Control LED anschalten
TCCR0 = 2;
TCCR1B = 3;
unsigned char sel = (PINC >> 1) & 0x07;
OCR1A = 30 + sel;
for (k=0;k<8;k++) data[k]=card_ID[2][k]; //Eine Zeile des Arrays emulieren
sbi(TIMSK, OCIE1A);
sei();
while (1) {
}
return 0;
}
Thanks