How to read a RFID card using MFRC522 - arduino-uno

I am trying to read a RFID tag/card using MFRC522. I have used the rfid-master library, and trying to read the card using the "dumpinfo" from "examples". but the serial monitor is showing me this-
WARNING: Communication failure, is the MFRC522 properly connected?
and of course not reading any card when I scan them. I have checked the port and it's connected to its legal comm port.
What can be a reason for this communication failure?
/*
* --------------------------------------------------------------------------------------------------------------------
* 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() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
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));
}

Are you the one who soldered the pins of mfrc522? I think you should double check your connection if it was shorted or not. Also if you're using 5v instead of 3.3v it might damage the mfrc522.

Related

STM32MP1 linux IRQs & EXTI controller config in DTS file

I'm running a buildroot linux environment on a STM32MP157 dev board. I have a button with an internal pullup on pin B12. I want to fire an interrupt once the line goes low. On other linux boards like the RPi, I've been able to call gpio_to_irq(<gpio#>) and get the IRQ for that pin. Done, simple. However, on this board, there are only 16 external interrupts connected to the EXTI peripheral; they are configurable in a sense that any port may be connected to the EXTI, but the pin numbers cannot overlap. For example GPIO A12 and B12 may NOT be connected to the EXTI at the same time. I have ensured that no other devices are using and GPIO port pin 12.
I have edited my DTS file to reflect that I want my GPIO B12 connected to the EXTI controller. But so far I have had no luck in making that happen. Here is the documentation for the interrupts provided by ST. If someone can explain how to fix the device tree such that I can request the B12 interrupt from my driver I would really appreciate it.
Here's my DTS file:
/dts-v1/;
#include "stm32mp157.dtsi"
#include "stm32mp15xa.dtsi"
#include "stm32mp15-pinctrl.dtsi"
#include "stm32mp15xxac-pinctrl.dtsi"
#include "stm32mp15xx-dkx.dtsi"
/ {
model = "STMicroelectronics STM32MP157A-DK1 Discovery Board";
compatible = "st,stm32mp157a-dk1", "st,stm32mp157";
chosen {
stdout-path = "serial0:115200n8";
};
button {
compatible = "test,button";
input-gpios = <&gpiob 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; //Works with pull-up once the driver is loaded.
interrupts-extended = <&gpiob 12 IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "qwerty";
status = "okay";
};
led {
extern-led {
compatible = "test,led";
gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "cpu";
};
};
};
I have tried the following:
interrupts-extended = <&exti 28 IRQ_TYPE_EDGE_FALLING>; (This SOC only has 16 pins per GPIO bank, so B12 is global GPIO 28)
interrupts-extended = <&gpiob 12 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpiob>;
interrupts = <12
IRQ_TYPE_EDGE_FALLING>;
Lastly, my stretch goal is to be able to request the IRQ by name, from the interrupt-name property in the device tree. Something like request_irq("qwerty"). Is that possible?
EDIT: I have temporarily connected my pushbutton to GPIO A12, and it successfully fires the interrupt, confirming that the EXTI #12 interrupt is connected to GPIO bank A. How can I go about changing this from within the device tree? Thank you in advance.
Okay I have solved this. Apparently iterating through your GPIO pins with the gpio*_to_irq() functions was the problem. When the function was called, the kernel would immediately configure the EXTI interface for that pin. I thought it was defaulting to Port A, but that was actually caused by iterating through all the GPIO pins looking for the interrupt number starting at GPIO 0, aka Port A Pin 0. So by only calling the gpio_to_irq or gpiod_to_irq function for the pins you need, the kernel will properly configure the EXTI interface for the requested pins.

Sending ASCII Commands to a TSI 5310 Flowmeter from a Teensy 3.5 with (Arduino IDE)

Introduction:
Okay so to start I just want to say that the sensor does send its data when commanded as I've tested this on Python connected to a COMPORT on a pc. I will include the Python Code I created that works with the sensor, so that all information is available to you guys. I also will include a link to the PJRC Forum that I've asked the same question on, because I've already gotten responses on the issue, but it still persists, and I want you guys to have what they've said at your disposal.
(Python Code & PJRC Link will be at the very bottom of the post)
Problem:
So, my problem is I cannot figure out how to properly send ASCII commands from the Teensy 3.5 and in return read the output of the Flowmeter with the Teensy 3.5. I am afraid that the hardware is connected wrong or I'm just going about something wrong.
The Serial Console will stay blank meaning nothing is available to be read in
What I've Tried - Software:
This is basic code I was given that should work for my use:
char s;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial && (millis() < 5000)) {};
Serial1.begin(115200);
delay(1000);
Serial1.print("?\r\n");
}
void loop() {
// put your main code here, to run repeatedly:
while (Serial1.available()){
s = Serial1.read();
Serial.print(s);
}
}
What I've Tried - Hardware:
Image of TSI FlowMeter 5130 w/Cables
Black Wire - USB_C to USB_A - connected to a 5v power supply
Blue/White Wire - USB_A to MALE DB9
Image of Cables that connect the Flowmeter & Teensy 3.5
Blue/White Wire - Male DB9
Tan Serial Gender Converter - Female DB9 to Female DB9
Black Converter Board - Male DB9 to 4-Wire TTL (Red - VCC, Yellow - Transmit, Blue - Receive, Black - GND)
Image of RS232 to TTL Wiring
Yellow Wire - Teensy Transmit Pin 1
Blue Wire - Teensy Receive Pin 0
Red Wire - Currently Set to 5v, but I've tried 3.3v to no avail
Black Wire - GND
Image of LEDs Wired into Rx/Tx of Teensy to watch for data being sent
Blue LED - (Yellow - Teensy Receive Pin 0, Orange - GND)
Green LED - (Red - Teensy Transmit Pin 1, Brown - GND)
Image - 5v Power Supply
White Wire - Teensy 5v
Purple Wire - Teensy GND
Python Code:
import serial
import time
index = 0
total = 0
i = 0
avg = 0
# Serial Connection
time.sleep(.5)
ser = serial.Serial(
port="COM2", baudrate = 115200,
parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS, timeout=1)
# Write ASCII Commands To TSI 5300 Flow Sensor
ser.write(b'?\r\n') # Ask Sensor if it is getting a signal (Returns "OK")
ser.write(b'SUS\r\n') # Set Flow type to SLPM (Returns "OK")
ser.write(b'SG0\r\n') # Set Flow Gas to Air (Returns "OK")
ser.write(b'SSR0005\r\n') # Set Sample Rate to 5ms (Returns "OK")
ser.write(b'LPZ\r\n') # Zero Low Pressure Sensor
# Read serial output to remove all 'OK's from buffer
while (i <= 4):
OK = ser.readline() # Read one line of serial and discard it
print(OK)
i += 1
# Ask for 5 Flow readings
ser.write(b'DAFxxxxx0005\r\n') # Read 5 sensor Flow Reading
ser.readline() # Read one line of serial data and discard it
byte = ser.readline() # Read one line of serial data and store it
print("Unfiltered Bytes: " + str(byte))
string = byte.decode('utf-8') # Convert from BYTE to STRING
array = string.split(',') # Convert from STRING to STRING ARRAY
print("String Array of all 5 readings: " + str(array))
# Convert each element of the ARRAY to FLOAT then add them together
for data in array:
index += 1
data = float(data)
total += data
avg = total / index # Find the average Flow in LPM
print("Average Flow Rate: " + str(avg) + " LPM")
time.sleep(1)
ser.close()
PJRC LINK:
https://forum.pjrc.com/threads/69679-Sending-ASCII-Commands-to-a-Teensy-3-5-Via-RS232-to-TTL-Converter
Yes, you should be able to connect it to the second USB port of the Teensy. This port acts as Host. Whether it works of course depends on which USB interface your flowmeter implements. If it implements some standard (e.g. CDC aka virtual serial or some HID interface) the USB Host lib can probably communicate with it. If they did a proprietary interface you would need to write a corresponding driver first...
I assume they implemented a CDC interface. You can easily check: if you connect the flowmeter to a PC a COM Port (Windows) should appear in the device manager.
I found the solution! It didn't matter which serial it was on (serial1 or serial2), however the problem is I had to start the teensy before the flowmeter and give the flowmeter 20sec to boot up before letting the teensy send any commands! This sensor is so slow though, it takes 50 seconds to fully boot up to the test screen! I just used a 5v relay to delay the flowmeter turning on. Thanks for your help!

Linux Device Tree: Touch controller failing i2c test

Context
I am using an i.MX6 ULL application processor with a Goodix 9271 touch-screen display. The display has been added to the device tree and is working correctly. I now wanted to add the touch controller, which is connected to my application processor via I²C. I therefore added
A new node under my I²C node which adds the controller as a device on the bus.
A new pin control group for the application processor to interface with the touch controller
I have enumerated them here:
/* #1: Device node on the I2C bus */
&i2c1 {
clock_frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
/* Awesome new touch controller */
gt9271_ts#5d {
compatible = "goodix,gt9271"; /* Device tree binding */
reg = <0x5d>; /* I2C bus address */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gt9271_ts_gpio>; /* Custom pinctrl group node */
interrupt-parent = <&gpio4>;
interrupts = <16,0>; /* GPIO 4 + pin 16 + active high */
reset-gpios = <&gpio4 12 0>; /* GPIO 4 + Pin 12 + active high */
touchscreen-size-x = <1200>;
touchscreen-size-y = <800>;
touchscreen-inverted-x;
touchscreen-inverted-y;
};
/* ... */
};
/* #2: Pin control group */
&iomuxc {
pinctrl_gt9271_ts_gpio: gt9271_ts_gpiogrp {
fsl,pins = <
MX6UL_PAD_NAND_DQS__GPIO4_IO16 0x80000000 /* Interrupt */
MX6UL_PAD_NAND_READY_B__GPIO4_IO12 0x80000000 /* Reset */
>;
};
/* ... */
};
Explanation: bus address
The device data sheet, available here, indicates that two slave addresses are supported: 0xBA/0xBB and 0x28/0x29. The device is set to use 0xBA/0xBB adjusted for 7-bit addressing as recommended in this binding, (so the address assigned in the node is actually 0x5d).
Explanation: control pins
The I²C reset and interrupt are connected (respectively) to GPIO 4, pin 16, and GPIO 4, pin 12. These are reserved for NAND but NAND is not being used with this processor so the pins are free.
Problem
Unfortunately, the touchscreen controller configuration I have added is failing on boot with an I²C related message. I am greeted on boot with the following:
[ 2.118110] Goodix-TS 0-005d: 0-005d supply AVDD28 not found, using dummy regulator
[ 2.126059] Goodix-TS 0-005d: 0-005d supply VDDIO not found, using dummy regulator
[ 2.134510] Goodix-TS 0-005d: i2c test failed attempt 1: -6
[ 2.177733] Goodix-TS 0-005d: i2c test failed attempt 2: -6
[ 2.217377] Goodix-TS 0-005d: I2C communication failure: -6
I have attempted to search the error code (-6) but find sparse to non-existent search results online. I've checked that the connector is physically there and it seems to be.
What steps might I take to diagnose such an error code?
The solution is as follows:
The documentation states that I should include the property in the format irq-gpios. I previously thought I only needed the interrupts property. After adding irq-gpios = <&gpio4 16 0>;, the device passed the I2C test.
I disabled touchscreen-inverted-x;, and touchscreen-inverted-y; by removing those lines. I had incorrectly assumed I needed to do that originally.
Verdict:
Try to follow the documentation precisely.

Serial Communication between two ESP32

I have found examples of basic arduino to arduino serial communication but have been unable to get those working on ESP32 boards. I am trying to make the same thing work between two ESP32's The two are connected:
esp1 esp2
gnd to gnd
tx2 to rx2
rx2 to tx2
Simple sketches:
//transmit sketch
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("test...");
delay(1000);
}
//receive sketch
void setup() {
Serial.begin(9600);
}
void loop() {
String received = "";
while (Serial.available())
{
received = Serial.read();
Serial.println(received);
}
}
What else is required to make this work?
I think your code comes from a simpler world in which pins were always fixed and one UART was all you had available. With the ESP32 you should probably look for a solution more along these lines:
#include <HardwareSerial.h>
HardwareSerial Serial2(2); // use uart2
Serial2.begin(19200, SERIAL_8N1, 16, 17); // pins 16 rx2, 17 tx2, 19200 bps, 8 bits no parity 1 stop bit
I hope this helps. If you still have problems after this, they're likely to be either a) the board you're using doesn't use 16 & 17 for rx2 & tx2, or b) you need 10k pull-up (not series) resistors on both lines to stop them "floating" - however some boards take care of the pull-ups for you.
All the following criteria should be meet to make it work:
ESP32 board should not use the serial port you want to use to any embedded feature. So it should be free to use.
Make sure you are using the right pins:
U
Rx
Tx
Serial
40
41
Serial1
9
10
Serial2
16
17
Make sure lines are crossed, so Tx is bind to Rx on the other board and vice versa.
Make sure that the speed is the same on both board.
To see the result both ESP32 board should be connected to the PC via USB and a console should attached to the USB ports. You can use putty for this purpose to connect the USB ports. Two instances can be run for the two USB port. Make sure the speed setup in putty is the same as it is in the code.
Whatever you type in one console will be transferred and will appear on the other console.
Upload this code to both ESP32 board:
HardwareSerial &hSerial = Serial1; //can be Serial2 as well, just use proper pins
void setup()
{
Serial.begin(115200);//open serial via USB to PC on default port
hSerial.begin(115200);//open the other serial port
}
void loop()
{
if (Serial.available()) //check incoming on default serial (USB) from PC
{
hSerial.write(Serial.read()); // read it from UBS and send it to hSerial
}
if (hSerial.available()) //check incoming on other serial from the other board
{
Serial.write(hSerial.read()); //read it from hSerial and send it to UBS
}
}

Example of use pwm_get() in linux kernel

I want to try to use PWM in linux kernel module for my Rasperry Pi. I've successfully enabled PWM via SYSFS interface.
For usage of pwm in kernel modules documentation states:
New users should use the pwm_get() function and pass to it the
consumer device or a consumer name. pwm_put() is used to free the PWM
device. Managed variants of these functions, devm_pwm_get() and
devm_pwm_put(), also exist.
pwm_get function looks like this:
/**
* pwm_get() - look up and request a PWM device
* #dev: device for PWM consumer
* #con_id: consumer name
....
*/
struct pwm_device *pwm_get(struct device *dev, const char *con_id)
Where I can find dev and con_id? I suspect that they should be defined in device tree, but it is only a suspicion.
One example of pwm_get() is available in the Intel PWM backlight
panel driver.
Here it is being used to obtain a PWM source by its name.
/* Get the PWM chip for backlight control */
panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
The PWM provider itself is defined
here...
/* PWM consumed by the Intel GFX */
static struct pwm_lookup crc_pwm_lookup[] = {
PWM_LOOKUP("crystal_cove_pwm", 0, "0000:00:02.0", "pwm_backlight", 0, PWM_POLARITY_NORMAL),
};
...and initialised
here.
/* Add lookup table for crc-pwm */
pwm_add_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup));
pwm-beeper is another example of pwm_get().
beeper->pwm = pwm_get(&pdev->dev, NULL);
A corresponding entry in the device tree is present here.
buzzer {
compatible = "pwm-beeper";
pwms = <&pwm 0 1000000 0>;
pinctrl-names = "default";
pinctrl-0 = <&pwm0_out>;
};
The inline documentation of pwm_get() describes both the ways it can be used.
/**
* pwm_get() - look up and request a PWM device
* #dev: device for PWM consumer
* #con_id: consumer name
*
* Lookup is first attempted using DT. If the device was not instantiated from
* a device tree, a PWM chip and a relative index is looked up via a table
* supplied by board setup code (see pwm_add_table()).
*
* Once a PWM chip has been found the specified PWM device will be requested
* and is ready to be used.
*
* Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
* error code on failure.
*/

Resources