#include <stdio.h>
#include <fcntl.h> /* File Control Definitions */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h> /* UNIX Standard Definitions */
#include <errno.h> /* ERROR Number Definitions */
#include <sys/ioctl.h> /* ioctl() */
void main(void)
{
int fd;/*File Descriptor*/
printf("\n +----------------------------------+");
printf("\n | USB To RS485 Write |");
printf("\n +----------------------------------+");
/*------------------------------- Opening the Serial Port -------------------------------*/
/* Change /dev/ttyUSB0 to the one corresponding to your system */
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY); /* ttyUSB0 is the FT232 based USB2SERIAL Converter */
/* O_RDWR Read/Write access to serial port */
/* O_NOCTTY - No terminal will control the process */
if(fd == -1) /* Error Checking */
printf("\n Error! in Opening ttyUSB0 ");
else
printf("\n ttyUSB0 Opened Successfully ");
/*---------- Setting the Attributes of the serial port using termios structure --------- */
struct termios SerialPortSettings; /* Create the structure */
tcgetattr(fd, &SerialPortSettings); /* Get the current attributes of the Serial port */
cfsetispeed(&SerialPortSettings,B4800); /* Set Read Speed as 9600 */
cfsetospeed(&SerialPortSettings,B4800); /* Set Write Speed as 9600 */
SerialPortSettings.c_cflag &= PARENB; /* Disables the Parity Enable bit(PARENB),So No Parity */
SerialPortSettings.c_cflag &= ~CSTOPB; /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
SerialPortSettings.c_cflag &= ~CSIZE; /* Clears the mask for setting the data size */
SerialPortSettings.c_cflag |= CS7; /* Set the data bits = 8 */
SerialPortSettings.c_cflag &= ~CRTSCTS; /* No Hardware flow Control */
SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines */
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); /* Disable XON/XOFF flow control both i/p and o/p */
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Non Cannonical mode */
SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing*/
/* Setting Time outs */
SerialPortSettings.c_cc[VMIN] = 1; /* Read at least 10 character */
SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly */
if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) /* Set the attributes to the termios structure*/
printf("\n ERROR ! in Setting attributes");
else
printf("\n BaudRate = 9600 \n StopBits = 1 \n Parity = none");
/*---------------------------------------- Controlling RTS and DTR Pins --------------------------------------*/
/* ~RTS(USB2SERIAL) ---> ~RE(MAX485) */
/* ~DTR(USB2SERIAL) ---> DE(MAX485) */
/*------------------------- Putting MAX485 chip in USB2SERIAL in Transmit Mode ---------------------------*/
// //
// ----+ +-----------+ H +-----------+ //
// | | ~RTS| --------------> |~RE | //
// PC |==========>| FT232 | | MAX485 +(A,B)~~~~~~~~~~~~~~~>Data out(RS485) //
// | USB | ~DTR| --------------> | DE | Twisted Pair //
// ----+ +-----------+ H +-----------+ //
// //
//--------------------------------------------------------------------------------------------------------//
//TxMode - DE->High,~RE -> High
int RTS_flag,DTR_flag;
RTS_flag = TIOCM_RTS; /* Modem Constant for RTS pin */
DTR_flag = TIOCM_DTR; /* Modem Constant for DTR pin */
ioctl(fd,TIOCMBIC,&RTS_flag);/* ~RTS = 1,So ~RE pin of MAX485 is HIGH */
ioctl(fd,TIOCMBIC,&DTR_flag);/* ~DTR = 1,So DE pin of MAX485 is HIGH,Transmit Mode enabled */
/*------------------------------- Write data to serial port -----------------------------*/
tcflush(fd, TCIFLUSH); /* Discards old data in the rx buffer */
char write_buffer[] = "///?01!"; /* Buffer containing characters to write into port */
char write_buffer1[] = {'\r','\n'};
int bytes_written = 0; /* Value for storing the number of bytes written to the port */
bytes_written = write(fd,write_buffer,7);/* use write() to send data to port */
/* "fd" - file descriptor pointing to the opened serial port */
/* "write_buffer" - address of the buffer containing data */
/* "sizeof(write_buffer)" - No of bytes to write */
printf("\n %s written to ttyUSB0",write_buffer);
bytes_written = write(fd,write_buffer1,2);/* use write() to send data to port */
/* "fd" - file descriptor pointing to the opened serial port */
/* "write_buffer" - address of the buffer containing data */
/* "sizeof(write_buffer)" - No of bytes to write */
printf("\n %s written to ttyUSB0",write_buffer);
printf("\n %d Bytes written to ttyUSB0", bytes_written);
printf("\n +----------------------------------+\n\n");
char buf[20000];
sleep(2);
while(1)
{
printf("tring to read port\n");
int res = read(fd,buf,1);
sleep(1);
printf("%c :: %d\n",buf[0],res);
}
printf("\n +----------------------------------+\n\n\n");
close(fd); /* Close the serial port */
}
--------------------------------------------------------
Setting for running the code :BAUD RATE is 4800 Databits is 7 , Parity is EVEN, and Stopbit is 1.
If i compile the code and run it is not working. Before running the code if i open and close the minicom with BAUD B4800 & 7E1 then my code is working.
Can any one suggest where is the problem why it is not working.
Related
Good day, I am working with a PIC24FJ64GA002 microcontroller and am struggling to get the PWM working for a servo I want to use. My code is as follows:
// PIC24FJ64GA002 Configuration Bit Settings
// 'C' source line config statements
// CONFIG2
#pragma config POSCMOD = NONE // Primary Oscillator Select (Primary oscillator disabled)
#pragma config I2C1SEL = PRI // I2C1 Pin Location Select (Use default SCL1/SDA1 pins)
#pragma config IOL1WAY = ON // IOLOCK Protection (Once IOLOCK is set, cannot be changed)
#pragma config OSCIOFNC = OFF // Primary Oscillator Output Function (OSC2/CLKO/RC15 functions as CLKO (FOSC/2))
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor (Clock switching and Fail-Safe Clock Monitor are disabled)
#pragma config FNOSC = FRC // Oscillator Select (Fast RC Oscillator (FRC))
#pragma config SOSCSEL = SOSC // Sec Oscillator Select (Default Secondary Oscillator (SOSC))
#pragma config WUTSEL = LEG // Wake-up timer Select (Legacy Wake-up Timer)
#pragma config IESO = ON // Internal External Switch Over Mode (IESO mode (Two-Speed Start-up) enabled)
// CONFIG1
#pragma config WDTPS = PS32768 // Watchdog Timer Postscaler (1:32,768)
#pragma config FWPSA = PR128 // WDT Prescaler (Prescaler ratio of 1:128)
#pragma config WINDIS = ON // Watchdog Timer Window (Standard Watchdog Timer enabled,(Windowed-mode is disabled))
#pragma config FWDTEN = ON // Watchdog Timer Enable (Watchdog Timer is enabled)
#pragma config ICS = PGx1 // Comm Channel Select (Emulator EMUC1/EMUD1 pins are shared with PGC1/PGD1)
#pragma config GWRP = OFF // General Code Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF // General Code Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG port is disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
/*
* File: 34660046LAB2.c
* Author: leone
*
* Created on 06 September 2021, 1:27 PM
*/
#include "p24FJ64GA002.h"
#include "xc.h"
#define _LATR15 OC1R
int main(void) {
T2CON = 0x8010;
TMR2=0;
PR2=9999;
_T2IP=4; //Default priority value
_T2IF=0; //Clears interrupt flag before interrupt
_T2IE=1; //Enables interrupt
OC1CONbits.OC = 0; // Output compare channel is disabled
OC1R = 0x1388 ; // Initialize Compare Register1 with 50% duty cycle
OC1CONbits.OCSIDL = 0; // Output capture will continue to operate in CPU Idle mode
OC1CONbits.OCFLT = 0; // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
OC1CONbits.OCTSEL = 0; // Timer2 is the clock source for output Compare
OC1CONbits.OCM = 0x6; // PWM mode on OC, Fault pin disabled
TRISBbits.TRISB15=0;
_LATB15=0;
while(1)
{
if(TMR2>OC1R)
{
_LATB15=1;
}
else
{
_LATB15=0;
}
}
return 0;
}
I programmed the T1CON to have a period of 2 ms, and the OC1R to have half that period, which should lead to a duty cycle of 50%. I am using the FRC oscillator (8MHz) and my pre-scaler values were <0,1>. I understand the it's the OC1R pin that gives the period the cycle is high, but in the datasheets they refer to it as a pin, however they don't give what pin it is (i.e. A0,A1,R15 etc.) There is also very little example code I could find explaining the how to code this well. If anyone is a PIC expert of some kind help would be very much appreciated! The datasheet for the MCU can be downloaded at https://www.microchip.com/en-us/product/PIC24FJ64GA002.
First of all configure the IO pins for PWM output, I assume you use SPDIP package and wanna use the OC1 PWM output pin:
// Unlock Registers
__builtin_write_OSCCONL(OSCCON & 0xBF);
// Configure Output Functions (Table 10-3)
// Assign OC1 To Pin RP2
RPOR1bits.RP2R = 18;
// Lock Registers
__builtin_write_OSCCONL(OSCCON | 0x40);
For the output pin configurations see the 10.4.3.2 Output Mapping section of the datasheet.
As per steps in the datasheet's 14.3 Pulse-Width Modulation Mode section:
Set the PWM period by writing to the selected Timery Period register (PRy). İf your period is 2 ms then compute the PRy register value:
#define Fosc ( 8000000 )
#define PWM_PERIOD_MS ( 2 )
#define PWM_FREQ_HZ ( 1000 / PWM_PERIOD_MS ) // In this case 500Hz
#define PRy_VALUE (uint16_t) ( (( Fosc ) / ( 4 * TMRyPS * PWM_FREQ)) - 1 )
// Somewhere in the init func or code assign the computed value for the period register
PRx = PRx_VALUE;
Set the PWM duty cycle by writing to the OCxRS register. Since you want a 50% duty cycle compute the value for OCxRS register:
#define DUTY (50)
#define DUTY_VALUE (uint16_t) ( ( 4 * ( TMRyPS - 1 ) * DUTY ) / 100 )
// Somewhere in the init func or code assign the computed value for the duty cycle register
OCxRS = DUTY_VALUE;
Write the OCxR register with the initial duty cycle. Assign the DUTY_VALUE to the OCxR register right after OCxRS assignment:
OCxR = DUTY_VALUE;
Enable interrupts, if required, for the timer and output compare modules. The output compare interrupt is required for PWM Fault pin utilization.
Configure the output compare module for one of two PWM Operation modes by writing to the Output Compare Mode bits, OCM<2:0>
(OCxCON<2:0>).
OC1CONbits.OCTSEL = 0; // Timer2 is the clock source for output Compare
OC1CONbits.OCM = 0x6; // PWM mode on OC, Fault pin disabled
Set the TMRy prescale value and enable the time base by setting TON (TyCON<15>) = 1.
T2CON = 0x0010 // Timer2 prescaler 1:8, internal clock
T2CON.TON = 1;
From now on you should have the PWM working if the above steps are done correctly. Modify your code as per instructions here. Then try it and let me know the result.
This is a complete application that builds with MPLABX v5.50 and XC16 v1.70:
/*
* File: main.c
* Author: dan1138
* Target: PIC24FJ64GA002
* Compiler: XC16 v1.70
* IDE: MPLABX v5.50
*
* Created on October 8, 2021, 1:12 PM
*
* PIC24FJ64GA002
* +-------------------:_:-------------------+
* ICD_VPP --> : 1 MCLR VDD 28 : <-- 3v3
* < > : 2 RA0/AN0 VSS 27 : <-- GND
* < > : 3 RA1/AN1 AN9/RP15/RB15 26 : < >
* ICD_PGD < > : 4 RB0/PGD1/AN2 AN6/RP14/RB14 25 : < >
* ICD_PGC < > : 5 RB1/PGC1/AN3 AN7/RP13/RB13 24 : < >
* PWM/OC1 < > : 6 RB2/RP2/SDA2/AN4 AN8/RP12/RB12 23 : < >
* < > : 7 RB3/RP3/SCL2/AN5 RP11/RB11 22 : <*>
* - > : 8 VSS RP10/RB10 21 : <*>
* < > : 9 RA2/OSCI VCAP 20 : <-- 10uF
* < > : 10 RA3/OSCO VSS 19 : <-- GND
* < > : 11 RB4/RP4 SDA1/RP9/RB9 18 : <*>
* < > : 12 RA4 SCL1/RP8/RB8 17 : <*>
* 3v3 --> : 13 VDD RP7/RB7 16 : <*>
* <*> : 14 RB5/RP5/PGD3 PGC3/RP6/RB6 15 : <*>
* +-----------------------------------------+
* DIP-28
* * Indicates 5.0 volt tolerant input pins.
*
* Description:
* Initialize the controller to use a system oscillator of 8MHz from the on chip Fast RC oscillator.
* Setup the OC1 function to provide a 4KHz square wave output on GPIO pin RB2.
*
* Notes:
* See: https://stackoverflow.com/questions/69453833/pwm-settings-in-pic24fj64ga002
*
*/
#pragma config POSCMOD = NONE, I2C1SEL = PRI, IOL1WAY = OFF, OSCIOFNC = ON
#pragma config FCKSM = CSECMD, FNOSC = FRC, SOSCSEL = SOSC, WUTSEL = LEG
#pragma config IESO = ON, WDTPS = PS32768, FWPSA = PR128, WINDIS = ON
#pragma config FWDTEN = OFF, ICS = PGx1, GWRP = OFF, GCP = OFF, JTAGEN = OFF
#include "xc.h"
/*
* Define the system oscillator frequency that this code will setup
*/
#define FSYS (8000000ul)
#define FCY (FSYS/2ul)
/*
* Initialize this PIC
*/
void PIC_Init(void) {
/* Disable all interrupt sources */
__builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
IEC0 = 0;
IEC1 = 0;
IEC2 = 0;
IEC3 = 0;
IEC4 = 0;
__builtin_disi(0x0000); /* enable interrupts */
CLKDIV = 0x0000; /* set for 8MHz FRC clock operations */
AD1PCFG = 0xffff; /* Set for digital I/O */
CMCON = 0x0000;
_NSTDIS = 1; /* disable interrupt nesting */
TRISA = 0xFFFF;
TRISB = 0xFFFF;
}
/*
* Initialize OC1 for PWM operation on PORTB bit RB2/RP2
*/
void OC1_Init(void) {
OC1CON = 0; /* turn off OC1 */
AD1PCFGbits.PCFG4 = 1; /* make GPIO RB2/RP2/AN4 a digital I/O pin */
LATBbits.LATB2 = 0; /* make GPIO RB2/RP2/AN4 output low */
TRISBbits.TRISB2 = 0; /* make GPIO RB2/RP2/AN4 a digital output */
_RP2R = 18; /* magic number to assign OC1 to RB2, see DS39881E-page 109 */
OC1CONbits.OCTSEL = 0; /* Use TIMER2 clock input and prescaler settings as clock for PWM count register */
OC1CONbits.OCM = 0b110; /* Set OC1 for PWM mode, fault shutdown disabled */
T2CON = 0; /* turn off TIMER2 */
T2CONbits.TCKPS = 0b00; /* set TIMER2 prescale as 1:1 */
T2CONbits.TCS = 0; /* set TIMER2 clock source as FSYS/2 */
PR2 = (FCY/4000ul)-1; /* set PWM period to 4KHz */
OC1RS = (PR2+1)>>1; /* set PWM duty cycle to 50% */
T2CONbits.TON = 1; /* turn on TIMER2 */
}
/*
* main application
*/
int main(void) {
PIC_Init();
OC1_Init();
/*
* application process loop
*/
for(;;) {
/* poll for start of PWM period */
if(IFS0bits.T2IF){
IFS0bits.T2IF= 0; /* put a breakpoint here to verify PWM timing with simulator stop watch */
Nop();
Nop();
Nop();
}
}
return 0;
}
This code does run correctly with the MPLABX simulation tool. This is almost never true. IMHO the MPLABX simulator is crap.
This is screen shot of the simulation session working:
An important note on the PIC24FJ64GA002 output compare module is that it is an early silicon implementation and the newer controllers have independent period count registers for each output compare module. This means that the output compare module periods are not tied to the TIMER period on these controllers. I mention this because it really confused me.
After reading https://www.quora.com/How-can-I-bypass-the-OS-buffering-during-I-O-in-Linux I want to try to access data on the serial port with the O_DIRECT option, but the only way I can seem to do that is by adding the GNU_SOURCE define but when I tried to execute the program, nothing at all is printed on the screen.
If I remove "#define _GNU_SOURCE" and compile, then the system gives me an error on O_DIRECT.
If I remove the define and the O_DIRECT flag, then incorrect (possibly outdated) data is always read, but the data is printed on the screen.
I still want to use the O_DIRECT flag and be able to see the data, so I feel I need an alternative command to printf and friends, but I don't know how to continue.
I attached the code below:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#define TIMEOUT 5
int main(){
char inb[3]; //our byte buffer
int nread=0; //number bytes read from port
int n; //counter
int iosz=128; //Lets get 128 bytes
int fd=open("/dev/ttyS0", O_NOCTTY | O_RDONLY | O_SYNC | O_DIRECT); //Open port
tcflush(fd,TCIOFLUSH);
for(n=0;n<iosz;n++){
int s=time(NULL); //Start timer for 5 seconds
while (time(NULL)-s < TIMEOUT && nread < 1){
inb[0]='A'; //Fill buffer with bad data
inb[1]='B';
inb[2]='C';
nread=read(fd,(char*)inb,1); //Read ONE byte
tcflush(fd,TCIOFLUSH);
if (nread < 0 || time(NULL)-s >= TIMEOUT){
close(fd); //Exit if read error or timeout
return -1;
}
}
printf("%x:%d ",inb[0] & 0xFF,nread); //Print byte as we receive it
}
close(fd); //program ends so close and exit
printf("\n"); //Print byte as we receive it
return 0;
}
First off, I'm no expert on this topic, just curious about it, so take this answer with a pinch of salt.
I don't know if what you're trying to do here (if I'm not looking at it the wrong way it seems to be to bypass the kernel and read directly from the port to userspace) was ever a possibility (you can find some examples, like this one but I could not find anything properly documented) but with recent kernels you should be getting an error running your code, but you're not catching it.
If you add these lines after declaring your port:
...
int fd=open("/dev/ttyS0", O_NOCTTY | O_RDONLY | O_SYNC | O_DIRECT );
if (fd == -1) {
fprintf(stderr, "Error %d opening SERIALPORT : %s\n", errno, strerror(errno));
return 1;
}
tcflush(fd,TCIOFLUSH);
....
When you try to run you'll get: Error 22 opening SERIALPORT : Invalid argument
In my humble and limited understanding, you should be able to get the same effect changing the settings on termios to raw, something like this should do:
struct termios t;
tcgetattr(fd, &t); /* get current port state */
cfmakeraw(&t); /* set port state to raw */
tcsetattr(fd, TCSAFLUSH, &t); /* set updated port state */
There are many good sources for termios, but the only place I could find taht also refers to O_DIRECT (for files) is this one.
I have a RFID-RC522 (MF-RC522) module and I'm using Arduino sketch program. I have downloaded the Example code:
/*
* --------------------------------------------------------------------------------------------------------------------
* Example sketch/program showing how to read data from a PICC to serial.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
* Reader on the Arduino SPI interface.
*
* When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
* then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When
* you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
* will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
* when removing the PICC from reading distance too early.
*
* If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
* So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
* details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
* keep the PICCs at reading distance until complete.
*
* #license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}
When I execute it, I get the message:
Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?
Scan PICC to see UID, SAK, type, and data blocks...
I have re-checked the connections a thousand time but it's not working, the pins are connected as the example says to, and the LED D1 is on (red). Does anyone can help me?
If anybody looking for a solution...
Step-1: Change the RST pin to 5 if you are using Arduino Uno or use RST pin 9 in Arduino Mega. the other pins remains the same.
Step-2:Download AddicoreRFID library.
Step-3: Open the Arduino IDE and navigate to Sketch > Include the Library using “Add .ZIP Library…” option.
Step-4: Restart the Arduino IDE (close and open again)
Step-5: Inside Arduino IDE Navigate to File > Examples > AddicoreRFID. Select the “Addicore_RFID_Example” sketch and upload the sketch
Step-6: Open the Serial window and select "Both NL & CR" and select "9600" for the baud rate option
Detail explanation can be found at link
This issue is due to incorrect wiring or loose contacts to RFID sensor. You need to solder contact to get results.
Also, choose appropriate PINS for your Arduino board.
UNO solution worked with me
Reset Bin is 5 not 10
Use 5V not 3.3v
Arduino forum Solution with explanation
Try this code
#include <RFID.h>
/*
* Pin layout should be as follows (on Arduino Uno):
* MOSI: Pin 11 / ICSP-4
* MISO: Pin 12 / ICSP-1
* SCK: Pin 13 / ISCP-3
* SS/SDA: Pin 10
* RST: Pin 9
*/
#include <SPI.h>
#include <RFID.h>
#define SS_PIN 10
#define RST_PIN 9
RFID rfid(SS_PIN,RST_PIN);
int self = 7;
int bat = 8;
int s = 6;
int serNum[5];
int cards[][5] = {
{42,249,70,213,64}
};
bool access = false;
void setup(){
Serial.begin(9600);
SPI.begin();
rfid.init();
pinMode(self, OUTPUT);
pinMode(bat ,OUTPUT);
pinMode(s,OUTPUT);
digitalWrite(self, LOW);
digitalWrite(bat , LOW);
}
void loop(){
if(rfid.isCard()){
if(rfid.readCardSerial()){
Serial.print(rfid.serNum[0]);
Serial.print(" ");
Serial.print(rfid.serNum[1]);
Serial.print(" ");
Serial.print(rfid.serNum[2]);
Serial.print(" ");
Serial.print(rfid.serNum[3]);
Serial.print(" ");
Serial.print(rfid.serNum[4]);
Serial.println("");
for(int x = 0; x < sizeof(cards); x++){
for(int i = 0; i < sizeof(rfid.serNum); i++ ){
if(rfid.serNum[i] != cards[x][i]) {
access = false;
break;
} else {
access = true;
}
}
if(access) break;
}
}
if(access){
Serial.println("Welcome!");
digitalWrite(bat,HIGH);
digitalWrite(self,HIGH);
delay(1000);
digitalWrite(self,LOW);
} else {
Serial.println("Not allowed!");
digitalWrite(s,HIGH);
delay(2000);
digitalWrite(s,LOW);
digitalWrite(bat,LOW);
}
}
rfid.halt();`enter code here`
}
I have an old system running a custom 2.6.15 kernel that uses libpcap (version 1.1.1). Recently I've changed my network card with Intel 82575EB chipset that requires me to update the driver to igb.ko (was e1000.ko). After the update, libpcap stop capturing packets. I modified a sample test code from tcpdump website that captures 1 packet and print the header information, libpcap return header.len of 1358 and header.caplen of 42, whereas in e1000 case, both packet.len and packet.caplen returns 1358. I've tried disabling MSI/MSI-X and increase the MTU but nothing works. Is there any other options I need to set to get the igb driver to work with libpcap?
Here's the sample test program (courtesy of tcpdump/libpcap team):
#include <pcap.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
pcap_t *handle; /* Session handle */
char dev[20]; /* The device to sniff on */
char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
struct bpf_program fp; /* The compiled filter */
bpf_u_int32 mask; /* Our netmask */
bpf_u_int32 net; /* Our IP */
struct pcap_pkthdr header; /* The header that pcap gives us */
const u_char *packet; /* The actual packet */
if (argc <= 1) return(1);
strcpy(dev, argv[1]);
/* Find the properties for the device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
net = 0;
mask = 0;
}
/* Open the session in promiscuous mode */
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
return(2);
}
/* Grab a packet */
packet = pcap_next(handle, &header);
/* Print its length */
printf("packet length [%d]; captured length [%d]\n", header.len, header.caplen);
/* And close the session */
pcap_close(handle);
return(0);
}
Try libpcap 1.4.0, which is currently the most recent release; there's a bug in 1.1.1 that, as I remember, could cause a packet to be supplied with a too-short caplen even though you've supplied a sufficiently-large snapshot length argument to pcap_open_live() (which you have - BUFSIZ is typically somewhere between 1K and 4K, both of which are bigger than 42, and I think it's 4K on Linux).
sniffex.c is a program that is based on libpcap , to sniff and display some packet information. How do i modify it so as to print the values of TCP flags - urg , ack , psh , rst , syn and fin ? please help..
If you check this code where sniff_tcp is used, make sure to print out
th_flags member of this structure which contians flags you need.
/* TCP header */
struct sniff_tcp {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
Generally you will have something like this (a bit ugly, you can do it better):
//this is already there in the code:
printf(" Src port: %d\n", ntohs(tcp->th_sport));
printf(" Dst port: %d\n", ntohs(tcp->th_dport))
//you add:
if (tcp->th_flags & TH_ECE){
printf(" Flag: TH_ECE");
}
if (tcp->th_flags & TH_RST){
printf(" Flag: TH_RST");
}