Incorrect Reading NPK Sensor - arduino
I want to read this sensor, it is an NPK Sensor. For this, I have this board, and this hat of this board to read the Mobus 485 link.
For this, the origin code that the hat gives us. To read the sensor I use the next tutorial, and finally the config of the NPK sensor:
Then after all of this, I generated this code:
#define PIN_5V_EN 0
#define CAN_TX_PIN 22
#define CAN_RX_PIN 21
#define RS485_TX_PIN 19
#define RS485_RX_PIN 18
#define RS485_EN_PIN 23
#define RE 23
#define DE 0
#include <Arduino.h>
#include <HardwareSerial.h>
#include <ModbusMaster.h>
// instantiate ModbusMaster object
ModbusMaster node;
HardwareSerial Serial485(2);
// Modbus RTU requests for reading NPK values
const byte water[] = {0x01, 0x03, 0x02, 0x01, 0x00, 0x01, 0xd4, 0x72};
const byte temp[] = {0x01, 0x03, 0x02, 0x00, 0x00, 0x01, 0x85, 0xb2};
const byte ec[] = {0x01, 0x03, 0x02, 0x02, 0x00, 0x01, 0x24, 0x72};
const byte ph[] = {0x01, 0x03, 0x02, 0x03, 0x00, 0x01, 0x75, 0xb2};
const byte nitro[] = {0x01, 0x03, 0x02, 0x04, 0x00, 0x01, 0xce, 0x73};
const byte phos[] = {0x01, 0x03, 0x02, 0x05, 0x00, 0x01, 0x95, 0xb3};
const byte pota[] = {0x01, 0x03, 0x02, 0x06, 0x00, 0x01, 0x65, 0xb3};
const byte dev_add[] = {0x01, 0x03, 0x10, 0x00, 0x00, 0x01, 0x80, 0xca};
const byte dev_baud[] = {0x01, 0x03, 0x10, 0x01, 0x00, 0x01, 0xd1, 0x0A};
// A variable used to store NPK values
byte values[11];
void CANTask(void *prarm);
void setup()
{
pinMode(RS485_EN_PIN, OUTPUT);
pinMode(PIN_5V_EN, OUTPUT);
Serial.begin(9600);
Serial485.begin(9600, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN);
delay(5);
node.begin(2, Serial485);
}
void loop()
{
static uint32_t i;
uint8_t j, result;
uint16_t data[6];
byte val1,val2,val3,val4,val5,val6,val7,val8,val9;
val1 = water_func();
delay(250);
val2 = temperature();
delay(250);
val3 = ec_func();
delay(250);
val5 = ph_func();
delay(250);
val5 = nitrogen();
delay(250);
val6 = phosphorous();
delay(250);
val7 = potassium();
delay(250);
val8 = dev_add_func();
delay(250);
val9 = dev_baud_func();
delay(250);
// Print values to the serial monitor
Serial.print("Water: ");
Serial.print(val1);
Serial.println(" mg/kg");
Serial.print("Tempetature: ");
Serial.print(val2);
Serial.println(" ºC");
Serial.print("EC: ");
Serial.print(val3);
Serial.println(" mg/kg");
Serial.print("PH: ");
Serial.print(val4);
Serial.println(" mg/kg");
Serial.print("Nitrogen: ");
Serial.print(val5);
Serial.println(" mg/kg");
Serial.print("Phosphorous: ");
Serial.print(val6);
Serial.println(" mg/kg");
Serial.print("Potassium: ");
Serial.print(val7);
Serial.println(" mg/kg");
Serial.print("Devive_Address: ");
Serial.println(val8);
Serial.print("Devive_Baud: ");
Serial.println(val8);
delay(20000);
}
byte water_func(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(water,sizeof(water))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte temperature(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(temp,sizeof(temp))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte ec_func(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(ec,sizeof(ec))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte ph_func(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(ph,sizeof(ph))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte nitrogen(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(nitro,sizeof(nitro))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte phosphorous(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(phos,sizeof(phos))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte potassium(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(pota,sizeof(pota))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte dev_add_func(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(dev_add,sizeof(dev_add))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte dev_baud_func(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(Serial485.write(dev_baud,sizeof(dev_baud))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
Serial.print(Serial485.read(),HEX);
values[i] = Serial485.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
But when I ran it, this is the output:
I think I have some issues with how to transmit the message and read it, any idea?
Thanks!!!
I don't have that sensor so be aware that I am guessing here but I can give you a couple of pointers that might help.
First of all, the datasheet for the sensor mentions the following:
The default baud rate is 4800bit / s and the default
address is 0x01
So the first thing to try is to select that baud rate:
Serial485.begin(4800, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN);
I have no idea why the tutorial goes for 9600 baud but it seems wrong.
The next thing you need to realize is that you are doing some things in your code that are redundant. You are loading the ModbusMaster.h library but not using it. You are instead sending and receiving Modbus frames manually.
The easiest thing to do is just drop the library by removing these lines:
#include <ModbusMaster.h>
// instantiate ModbusMaster object
ModbusMaster node;
....
node.begin(2, Serial485);
But my preferred solution would be to actually use the library (do not reinvent the wheel, right?).
This is a short example to read temperature values from your sensor with ModbusMaster.h:
#define PIN_5V_EN 0
#define CAN_TX_PIN 22
#define CAN_RX_PIN 21
#define RS485_TX_PIN 19
#define RS485_RX_PIN 18
#define RS485_EN_PIN 23
#define RE 23
#define DE 0
#include <Arduino.h>
#include <HardwareSerial.h>
#include <ModbusMaster.h>
// instantiate ModbusMaster object
ModbusMaster node;
HardwareSerial Serial485(2);
// Modbus RTU requests for reading NPK values
// These are not needed, the library will do its magic
// A variable used to store NPK values
byte values[11];
void setup()
{
pinMode(RS485_EN_PIN, OUTPUT);
pinMode(PIN_5V_EN, OUTPUT);
Serial.begin(9600);
Serial485.begin(4800, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN); // Changed to 4800, default value
delay(5);
node.begin(1, Serial485); // Changed to ID=1, default value
}
void loop()
{
uint8_t result;
uint16_t data_temperature;
result = node.readHoldingRegisters(0x0200, 1); // use library to read holding register 0x0200, just 1 register that contains the temperature
// do something with data if read is successful-->store
if (result == node.ku8MBSuccess) {
data_temperature = node.getResponseBuffer(0);
}
// Print values to the serial monitor
Serial.print("Tempetature: ");
Serial.print(data_temperature/100); //scale divinding by 100
Serial.println(" ºC");
delay(20000);
}
As you can see I've changed both the baud rate and the Modbus slave ID to 1 with node.begin(1, Serial485); to keep the default values as per the datasheet.
If you you use the library you don't have to take care of building, sending and receiving frames. Plus the CRCs are calculated and checked for you.
Finally, a couple of things that are really useful when you are debuggin a project like yours are:
A USB RS485 adaptor for your laptop/desktop computer. If you have one of these you can connect to your sensor using something like QModMaster then you can check the correct baud rate or what registers to read directly from a GUI instead of messing with code.
A scope makes the job much easier. You can check the wiring is correct and really see the frames running on the bus.
You can get a glimpse of how easy it easy to debug the configuration and map register of a Modbus device just following these steps (you should get the same temperature value you got using the Arduino code above):
-Download, extract and run QModMaster (qModMaster.exe). You might need to run as administrator.
-Set up your port selecting Modbus RTU from menu Options:
You might need to go to your Device Manager to check your port number. Other settings are the same as for your board.
-Save your settings by clicking OK. Now at the main window change Function Code to Read Holding Registers (0x03) and choose value 512 (0x0200) for Start Address , you should see something like this:
-Finally, go to Connect on menu Commands or click on the third icon starting from the left. Your temperature value (multiplied by 100) should appear on the first register (the box showing -/- just before connecting).
If you don't get the value, the only problem could be either something wrong with your sensor (power or otherwise) or a wiring issue. For my USB adaptor I'd have to connect A+, B- and GND (do not forget that one):
Related
arduino accelerometer with servo motor
I'm currently working on project to operate three motors while sending accelerometer value to computer via bluetooth module. I want the motor operation and value transmission to work seperatly. But when motors operate, the transmission stops. I used the ArduinoThread library, but since I don't understand all the usage, it still has some kind of delay. Plus, I want two of the motors work first(just once) and the other works after specific time(also just once). But the first setup of two motors and the latter doesn't work. Please check my code and give me some advice. Thank you! #include <Wire.h> #include <SoftwareSerial.h> #include <Servo.h> #include <Thread.h> const int MPU_addr=0x68; // MPU-6050 I2C address int16_t AcX,AcY,AcZ,GyX,GyY,GyZ; SoftwareSerial BTSerial(3,2); // TX,RX Servo servoMini; Servo servoUp; Servo servoDown; int pinMini = 6; int pinUp = 9; int pinDown = 10; int i = 1; unsigned long tPrev, tNow = 0; Thread myThread = Thread(); void readAcc(){ Wire.endTransmission(true); Wire.beginTransmission(MPU_addr); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers // 14bit?? AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) //AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) //AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) //GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) //GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) //GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) BTSerial.println(AcX); // 16bit Serial.println(AcX); // delay(25); } void setup(){ // I2C Wire.begin(); Wire.beginTransmission(MPU_addr); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) // serial, bluetooth Serial.begin(9600); BTSerial.begin(9600); Serial.println("CLEARDATA"); Serial.println("ONLY AcX"); // servo servoMini.attach(pinMini); servoUp.attach(pinUp); servoDown.attach(pinDown); pinMode(pinMini, OUTPUT); pinMode(pinUp, OUTPUT); pinMode(pinDown, OUTPUT); servoMini.write(145); servoUp.write(180); servoDown.write(0); // Thread(MPU-6050) myThread.onRun(readAcc); myThread.setInterval(20); } void loop(){ while(i == 1){ //delay(1000); tNow = millis(); myThread.run(); servoUp.attach(pinUp); servoDown.attach(pinDown); servoUp.write(60); servoDown.write(120); if((tNow - tPrev)>= 1000){ servoMini.attach(pinMini); servoMini.write(180); i++; } } servoMini.detach(); myThread.run(); }
I think you probably need something like this? #include <Wire.h> #include <SoftwareSerial.h> #include <Servo.h> #include <Thread.h> const int MPU_addr = 0x68; // MPU-6050 I2C address int16_t AcX, AcY, AcZ, GyX, GyY, GyZ; SoftwareSerial BTSerial(3, 2); // TX,RX Servo servoMini; Servo servoUp; Servo servoDown; int pinMini = 6; int pinUp = 9; int pinDown = 10; int i = 1; unsigned long tPrev, tNow = 0; Thread accelleroThread = Thread(); Thread servoThread = Thread(); void main() { setup(); // Thread(MPU-6050) accelleroThread.onRun(readAcc); accelleroThread.setInterval(20); // Thread(MPU-6050) servoThread.onRun(controlServo); servoThread.setInterval(20); accelleroThread.run(); servoThread.run(); } void setup() { // I2C Wire.begin(); Wire.beginTransmission(MPU_addr); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) // serial, bluetooth Serial.begin(9600); BTSerial.begin(9600); Serial.println("CLEARDATA"); Serial.println("ONLY AcX"); // servo servoMini.attach(pinMini); servoUp.attach(pinUp); servoDown.attach(pinDown); pinMode(pinMini, OUTPUT); pinMode(pinUp, OUTPUT); pinMode(pinDown, OUTPUT); servoMini.write(145); servoUp.write(180); servoDown.write(0); } void readAcc() { while (1) { Wire.endTransmission(true); Wire.beginTransmission(MPU_addr); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers // 14bit?? AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) //AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) //AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) //GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) //GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) //GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) BTSerial.println(AcX); // 16bit Serial.println(AcX); // delay(25); } } void controlServo() { while (1) { //delay(1000); tNow = millis(); myThread.run(); servoUp.attach(pinUp); servoDown.attach(pinDown); servoUp.write(60); servoDown.write(120); if ((tNow - tPrev) >= 1000) { servoMini.attach(pinMini); servoMini.write(180); i++; } } servoMini.detach(); } Note I just moved some blocks around to get 2 threads running (1 controlling the servo, 1 reading the accellero).
Need to know how to send HEX values via SoftwareSerial on Arduino Uno
I’m trying to write Android Uno code to send HEX values via SoftwareSerial but when watching the Serial Monitor the output isn’t what I expected or wanted, and I am not experienced enough yet to know what to do next. I don’t know where the FFFFs come from to be able to eliminate them. My desired output is: <br> AA130120<br> AA0400AE What I get is: <br> FFFFFFFFAA1311E<br> FFFFFFAA20 My code: #include <SoftwareSerial.h> // Define the RX and TX pins to establish UART communication with the MP3 Player Module. #define Pin_RX 0 // to RX #define Pin_TX 1 // to TX #define d_sleep 10000 // Define the required MP3 Player Commands: static byte ccPlay[] = {0xAA, 0x02, 0x00, 0xAC}; // Play: static byte ccSetVol[] = {0xAA, 0x13, 0x01, 0x20}; // Set Volume (00-30): // Define the Serial MP3 Player Module. SoftwareSerial MP3(Pin_RX, Pin_TX); void setup() { // Initiate the serial monitor. Serial.begin(9600); } void loop() { // Play a song. ccSetVol[3] = {0x1E}; send_command_to_MP3_player(ccSetVol, 4); delay(d_sleep); send_command_to_MP3_player(ccPlay, 4); delay(d_sleep); } void send_command_to_MP3_player(int8_t command[], int len){ //Serial.print("\nMP3 Command => "); for (int i=0; i<len; i++) { MP3.write(command[i]); Serial.print(command[i], HEX); } delay(100); }
Could you set the baud rate in the serial monitor to 9600Bd, run this code, and see if it spits out the bytes you expect in the serial monitor? #define d_sleep 10000 static byte ccPlay[] = {0xAA, 0x02, 0x00, 0xAC}; static byte ccSetVol[] = {0xAA, 0x13, 0x01, 0x20}; void send_command_to_MP3_player(byte command[], int len) { for (int i=0; i<len; i++) { //Serial.println(command[i], HEX); Serial.print(command[i], HEX); } //Serial.println(); delay(100); } void setup() { Serial.begin(9600); delay(1500); } void loop() { ccSetVol[3] = 0x1E; send_command_to_MP3_player(ccSetVol, 4); delay(d_sleep); send_command_to_MP3_player(ccPlay, 4); delay(d_sleep); }
ENC28j60 Arduino does not show decimals
I am using ENC28j60 with temp sensor in Arduino uno to see the temperature on the internet, but the problem is that it does not show decimals And shows only the integer. Image of Issue enter code here#include <OneWire.h> #include <DallasTemperature.h> #define DS18B20 2 OneWire ourWire(DS18B20); DallasTemperature sensors(&ourWire); float TempDS; #include "etherShield.h" #include "ETHER_28J60.h" static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24}; static uint8_t ip[4] = {192, 168, 0, 15}; static uint16_t port = 80; ETHER_28J60 ethernet; void setup(){ ethernet.setup(mac, ip, port); Serial.begin(9600); delay(1000); sensors.begin(); } void loop(){ sensors.requestTemperatures(); TempDS = sensors.getTempCByIndex(0); Serial.print(TempDS); Serial.println(" C"); if (ethernet.serviceRequest()){ ethernet.print("<H1>Hello World</H1>"); ethernet.print( TempDS ); ethernet.respond();} }
ETHER_28J60's print either takes a char pointer or an integer. You're stuffing a float into it so you're losing the decimals. Convert your float to a string
Multiple Slave SPI on ESP8266 - PN532 and ILI9341
Im trying to interface ESP12-E module with ILI9341 display 320*240 And PN532 RFID reader on the same SPI bus. I have assigned SS Pins on different GPIO. Im unable to Communicate with both. Display works perfectly in any conditions. But once i communicate with ILI9341 , the PN532 stops working and it will not respond until i restart the device even if i reinitialize it. Any Help would be highly Appreciated My Code : #include <Wire.h> #include <SPI.h> #include <Adafruit_PN532.h> #include <UTFT.h> UTFT lcd(ILI9341_S5P,15,D1,D3); // If using the breakout with SPI, define the pins for SPI communication. #define PN532_SS (D4) #define PN532_SCK (D5) #define PN532_MOSI (D7) #define PN532_MISO (D6) // If using the breakout or shield with I2C, define just the pins connected // to the IRQ and reset lines. Use the values below (2, 3) for the shield! #define PN532_IRQ (2) #define PN532_RESET (3) // Not connected by default on the NFC Shield // Uncomment just _one_ line below depending on how your breakout or shield // is connected to the Arduino: // Use this line for a breakout with a SPI connection: Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); // Use this line for a breakout with a hardware SPI connection. Note that // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin. //Adafruit_PN532 nfc(PN532_SS); // Or use this line for a breakout or shield with an I2C connection: //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); extern uint8_t BigFont[]; void setup(void) { Serial.begin(115200); Serial.println("Hello!"); nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (! versiondata) { Serial.print("Didn't find PN53x board"); while (1); // halt } // Got ok data, print it out! Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC); lcd.InitLCD(); lcd.setColor ( 0, 0, 0 ); lcd.fillRect(1,1,319,239); lcd.setColor ( 255, 255, 255 ); lcd.fillRect(100,100,220,140); lcd.setFont ( BigFont ); lcd.print(String("Scanning"),0,0); // Set the max number of retry attempts to read from a card // This prevents us from waiting forever for a card, which is // the default behaviour of the PN532. nfc.setPassiveActivationRetries(0xFF); // configure board to read RFID tags nfc.SAMConfig(); Serial.println("Waiting for an ISO14443A card"); } void loop(void) { boolean success; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) // Wait for an ISO14443A type cards (Mifare, etc.). When one is found // 'uid' will be populated with the UID, and uidLength will indicate // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength,25); if (success) { Serial.println("Found a card!"); Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes"); Serial.print("UID Value: "); for (uint8_t i=0; i < uidLength; i++) { Serial.print(" 0x");Serial.print(uid[i], HEX); } Serial.println(""); // Wait 1 second before continuing delay(1000); } else { // PN532 probably timed out waiting for a card //Serial.println("Timed out waiting for a card"); } }
I've testing it a lot and figured out - The SPI bit-order is different, so you can not drive these two devices on the same SPI. But you can use SW-SPI (bitbanging) for the NFC module, because it is not necessary to drive it fast. The TFT instead must be fast to have good update rates. One Issue is still open on my setup: the display did not show content, if you have an open serial terminal. But when it is closed, both TFT and NFC are working fine together. Here is my code: #include <ESP8266WiFi.h> #include <Wire.h> #include <SPI.h> #include <Adafruit_PN532.h> #include <UTFT.h> // NFC module #define PN532_SCK D1 #define PN532_MOSI D2 #define PN532_MISO D3 #define PN532_SS D0 Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); // TFT display // HSPI defines #define TFT_SCK D5 #define TFT_MOSI D7 //#define TFT_MISO D6 (not connected) #define TFT_CS D8 #define TFT_DC D4 UTFT myGLCD(ILI9341_S5P, TFT_CS, -1, TFT_DC); // Declare which fonts we will be using extern uint8_t SmallFont[]; extern uint8_t BigFont[]; // forward declaration of helper function to get UID as HEX-String void byteToHexString(String &dataString, byte *uidBuffer, byte bufferSize, String strSeperator); void setup() { Serial.begin(9600); Serial.println("Initial nfc module"); nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (! versiondata) { Serial.print("Didn't find PN53x board"); while (1); // halt } // Got ok data, print it out! Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC); // Set the max number of retry attempts to read from a card // This prevents us from waiting forever for a card, which is // the default behaviour of the PN532. nfc.setPassiveActivationRetries(0xFF); // configure board to read RFID tags nfc.SAMConfig(); Serial.println("Waiting for an ISO14443A card"); Serial.println("Initial tft display"); myGLCD.InitLCD(); myGLCD.setColor(0, 0, 0); myGLCD.fillRect(1,1,319,239); myGLCD.setColor(255, 255, 255); myGLCD.setFont(BigFont); myGLCD.print(String("Scanning"),0,0); } void loop(void) { boolean success; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) // Wait for an ISO14443A type cards (Mifare, etc.). When one is found // 'uid' will be populated with the UID, and uidLength will indicate // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); //success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength,25); if (success) { Serial.println("Found a card!"); Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes"); Serial.print("UID Value: "); String strUID; // store UID as HEX-String to strUID and print it to display byteToHexString(strUID, uid, uidLength, "-"); Serial.println(""); Serial.println(strUID); myGLCD.print(strUID, CENTER, 50); myGLCD.setColor ( 255, 0, 0 ); myGLCD.setFont ( BigFont ); myGLCD.print(String("Scanning"),0,0); // Wait 1 second before continuing delay(1000); } else { Serial.println("Timed out or waiting for a card"); } } // helper function to get UID as HEX-String void byteToHexString(String &dataString, byte *uidBuffer, byte bufferSize, String strSeperator=":") { dataString = ""; for (byte i = 0; i < bufferSize; i++) { if (i>0) { dataString += strSeperator; if (uidBuffer[i] < 0x10) dataString += String("0"); } dataString += String(uidBuffer[i], HEX); } dataString.toUpperCase(); }
Thanks for the help. Im not a big fan of bitbanging SPI. I have tried several ways and tried re-initializing, etc. Finally, i got it solved. I dont know why, but when i re-initialize spi hardware after reading card, Both of the module works perfectly. The code i added just after reading card: lcd._hw_special_init(); like: success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength,0); if (success) { lcd._hw_special_init(); //Do the rest }
How can i make arduino send sensor data to server using wifi?
So what i have so far in my code is to make my arduino able to send accelerometer and gyroscope data using Ethernet but I cant figure out how to make it wireless. here is what i have so far: ` #include #include #include Byte mac[] = { 0x00, 0Xaa, 0xbb, 0xcc, 0xde 0x01 }; // Reserved Mac Address EthernetClient client; #define DHTPIN 2 // SENSOR PIN #define DHTTYPE DHT11 // SENSOR TYPE DHT dht(DHTPIN, DHTTYPE); long previousMillis = 0; unsigned long currentMillis= 0; long interval = 250000; //READING INTERVAL int t = 0; // TEMPERATURE VAR int h = 0; // HUMIDITY VAR String data; Void setup() { Serial.begin(115200); If (Ethernet.begin(mac) == 0) { Serial.println(“Failed to configure Ethernet using DHCP”); } dht.begin(); delay(10000); // GIVE THE SENSOR SOME TIME TO START h = (int) dht.readHumidity(); t = (int) dht.readTemperature(); data = “”; } void loop(){ currentMillis = millis(); if(currentMillis – previousMillis > interval) { //READ ONLY ONCE PER INTERVAL previousMillis = currentMillis; h = (int) dht.readHumidity(); t = (int) dht.readTemperature(); } data = “templ=” + t + “&hum1=” + h; //THIS IS FOR PRINTING DATA TO WEBPAGE if (client.connect(www.*****.*************.com,80)) { //REPLACE WITH SERVER ADDRESS client.println(“POST /add.php HTTP/1.1”); client.println(“Host: *****.*************.com,80”); //SERVER ADDRESS HERE TOO client.println(“Content-Type: application/x-www-form-urlencoded”); client.print(“Content-Length: “); client.println(data.length()); client.println(); client.print(data); } If (client.connected()) { client.stop(); //Disconnect from the server } delay(300000); //Wait five minutes before sending again } ` thank you
You'll need a WiFi module like ESP8266. You can also use it alone (without arduino) since it is a complete soc with io pins.
For small range you can use Xbee module or Bluetooth shield. For range, GSM shield is recommmended.