ESP8266 (Nodemcu) + PN532 (RFID) + ST7735 (Display) in one setup possible? - arduino

I am trying to get an RFID-Reader (PN532) to work with a display, so it is shown there, who has scanned his RFID-Card.
The problem I ran into was, that 2 pins (D7 HMOSI) and (D5 HSLCK) are used by both devices. Thus I simply put both connections on those. (wrong?)
Now when initializing either of both devices, the other one gets disabled.
I use Adafruit to initialize both devices.
In addition to this, the ESP8266 does not start when the RFID-Reader is connected. Removing the Pin from 3.3Volt VCC and waiting for init, then Adding the Pin, only then the RFID-Reader gets recognized and the ESP8266 runs. (bad case for crashes, as it would never reboot)
This is my cable setup:
Also here is my code:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>
#define PN532_SCK (14)
#define PN532_MOSI (13)
#define PN532_SS (15)
#define PN532_MISO (12)
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#define TFT_CS 5
#define TFT_RST 16
#define TFT_DC 4
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
void testdrawtext(char *text, uint16_t color) {
tft.setCursor(0, 0);
tft.setTextColor(color);
tft.setTextWrap(true);
tft.print(text);
}
void setup(void) {
Serial.begin(9600);
Serial.print(F("Hello! ST7735 TFT Init"));
tft.initR(INITR_BLACKTAB); // Init ST7735 chip, black tab
Serial.println(F("Initialized"));
tft.fillScreen(ST77XX_BLACK);
while (!Serial) delay(10);
Serial.println("Hello! PN532 RFID Init");
nfc.begin(); // Init PN532 chip
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN532 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);
nfc.setPassiveActivationRetries(0xFF);
nfc.SAMConfig();
Serial.println("Waiting for a Card");
}

The constructor
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
creates a 'driver' which uses software SPI. But you supply pins of hardware SPI as parameters. Hardware SPI is used by the Adafruit_ST7735 library over the SPI library to access the display so hardware SPI conflicts with the software SPI of the PN532 library.
Use
Adafruit_PN532 nfc(PN532_SS);
constructor which uses the hardware SPI over the SPI library. The SPI library 'knows' the pin numbers of the SPI pins. (SPI library is part of the boards package. It can't be installed separately.)
And don't use SS (io 15) as CS. Use a different pin. io 15 is a boot configuration pin and must be LOW at boot.

Related

Arduino Nano communication with ST7735 over SPI-Bus

I use an Arduino Nano with a ST7735 display and a CAN controller MCP2515. Via SPI bus I want to communicate with the display and the CAN controller. The communication via CAN controller works smoothly. With the display I have the problem that it only shows a white screen.
This is my current setup:
CAN-Setup as picture
I use this kind of code to communicate with the CAN-Controller and with the display:
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>
#include <mcp2515.h>
#define MCP2515_CS 10 // Chip Select CAN-Controller
#define TFT_CS 7 // Chip Select TFT-Display
#define TFT_RST 8 // Reset
#define TFT_DC 9
#define TFT_MOSI 11 // Data out
#define TFT_SCLK 13 // Clock out
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
struct can_frame canMsg;
MCP2515 mcp2515(MCP2515_CS);
Can anyone spot a bug?
In Adafruit libraries the constructors where you enter the SPI pins use software SPI (bit banged). It conflicts with hardware SPI for the CAN controller on the same pins. Use the constructor
Adafruit_ST7735(int8_t cs, int8_t dc, int8_t rst);
so
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

Arduino communication with TMC2209

I'm trying to communicate with TMC2209 (stepper drive) with an Arduino nano Every.
I connected pin RX on pin D2 and TX on pin D3.
I placed a 1K resistor between TX and RX.
It seems I can write parameters (even I'm testing this deeply, I'm not so sure now..) but I'm not able
to read nothing from driver.
Picture added 15/04/2021 related to datasheet of TMC2209
In my test, I tried with only one driver with address 0, means MS1_AD0 and MS2_AD1 connected to GND.
driver1.microsteps(MICROSTEPS);
SerialPort.print("Counter1=");
SerialPort.print(driver1.IFCNT());
SerialPort.print(", Status=");
SerialPort.println(driver1.DRV_STATUS());
I tried reading IFCNT and DRV_STATUS, always ZERO.
The initialization is done in this way:
#include <Wire.h>
#include <AG_AS5600.h>
#include <TMCStepper.h>
#include <AccelStepper.h>
#define ENCODER false
#define FEEDBACK_I2C true
#define GEARBOX 139 //51
#define MICROSTEPS 16
#define MIN_SPEED 20
#define MAX_SPEED 3000
double offsetHome = 77.0;
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SerialPort SerialUSB
#define SYS_VOL 3.3
#else
#define SerialPort Serial
#define SYS_VOL 5
#endif
#define SW_RX 2 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX 3 // TMC2208/TMC2224 SoftwareSerial transmit pin
#define EN_PIN 7 // Enable
#define DIR_PIN 8 // Direction
#define STEP_PIN 9 // Step
#define SERIAL_PORT Serial1 // TMC2208/TMC2224 HardwareSerial port
#define DRIVER_ADDRESS1 0b00 // TMC2209 Driver address according to MS1 and MS2
#define R_SENSE 0.11f // Match to your driver
// SilentStepStick series use 0.11
// UltiMachine Einsy and Archim2 boards use 0.2
// Panucatt BSD2660 uses 0.1
// Watterott TMC5160 uses 0.075
AG_AMS_5600 ams5600;
TMC2209Stepper driver1(SW_RX, SW_TX, R_SENSE, DRIVER_ADDRESS1);
AccelStepper stepper = AccelStepper(stepper.DRIVER, STEP_PIN, DIR_PIN);
String cmd = {};
void setup()
{
SerialPort.begin(115200);
Wire.begin();
Wire.setTimeout(10);
SerialPort.println(">>>>>>>>>> Program started <<<<<<<<<<");
pinMode(EN_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
digitalWrite(EN_PIN, HIGH); // Enable driver in hardware
// Enable one according to your setup
SPI.begin(); // SPI drivers
driver1.beginSerial(115200); // SW UART drivers
driver1.begin(); // SPI: Init CS pins and possible SW SPI pins
// UART: Init SW UART (if selected) with default 115200 baudrate
driver1.toff(5); // Enables driver in software
driver1.rms_current(2000); // Set stepper current to 600mA. The command is the same as command TMC2130.setCurrent(600, 0.11, 0.5);
driver1.microsteps(MICROSTEPS);
driver1.pwm_autoscale(true); // Needed for stealthChop
stepper.setMaxSpeed(degToSteps(500.0)); // steps/s
stepper.setAcceleration(degToSteps(1.0)); // steps/s^2
stepper.setEnablePin(EN_PIN);
stepper.setPinsInverted(false, false, true);
stepper.disableOutputs();
}
void loop()
{
unsigned long t0 = micros();
switch (step) {
case 0:
cmd = SerialPort.readString();
if (cmd.charAt(0)=='a' && cmd.charAt(1)=='=') {
acc = degToSteps(cmd.substring(2).toDouble());
SerialPort.print("Acceleration=");
SerialPort.println(acc);
cmd = "";
}
else if (cmd.charAt(0)=='d' && cmd.charAt(1)=='=') {
dec = cmd.substring(2).toInt();
SerialPort.print("Deceleration=");
SerialPort.println(dec);
cmd = "";
}
else if (cmd.charAt(0)=='c' && cmd.charAt(1)=='?') {
driver1.microsteps(MICROSTEPS);
driver2.microsteps(MICROSTEPS);
SerialPort.print("Counter1=");
SerialPort.print(driver1.IFCNT());
SerialPort.print(", Counter2=");
SerialPort.print(driver2.IFCNT());
SerialPort.print(", Status=");
SerialPort.println(driver1.DRV_STATUS());
cmd = "";
}
}
The hardware should be ok because the jumper for UART is configured as default on pin4.
Can someone help me to understand why?
Thanks
Andrea
I found!
The issue was the handling of "software" serial port.
Unfortunately I was confused because many examples of "TMCstepper.h" library are shown using two pins as TX and RX, so I was convinced internally pins were handled to send and receive.. but it's not.
So solution I found is:
#include <SoftwareSerial.h>
SoftwareSerial SerialDriver1(SW_RX, SW_TX);
TMC2209Stepper driver1(&SerialDriver1, R_SENSE, DRIVER_ADDRESS1);
void setup()
{
SerialDriver1.begin(57600);
SerialDriver1.listen();
...
and was really important to comment:
//driver1.beginSerial(115200); // SW UART drivers
this is important I guess because the port was already opened in the setup by me.
and it's necessary to specify the software port where to listen, not done by TMC library.
Last hint, with Arduino Nano Every I found out that Software Serial seems to work with max baudrate of 57600, 115200 was not working.

OLED (I2C) and Micro SD card module not working together in Arduino

I am trying to write some data to SD card and read it back to serial monitor as well as display it to the OLED.
Both the SD card and OLED work separately but they seem to be interfering with each other when combined. I have used Arduino SD and Adafruit OLED libraries.
Connections from Arduino Uno to Micro SD card module:
5V to SD VCC
GND TO SD GND
PIN 10 TO SD Chip Select
PIN 11 TO SD MOSI
PIN 12 TO SD MISO
PIN 13 TO SD SCK
Connections to OLED:
3.3V to OLED VCC
GND TO OLED GND
A4 TO OLED SDA
A5 TO OLED SCK
Here is the code:
#include <SPI.h>
#include <SD.h>
File myFile;
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while(!Serial) {
;
}
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // CODE GETS STUCK HERE. DISPLAY NEVER INITIALISES
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(29,29);
display.print("INITIALISING");
display.display();
delay(5000);
if (!SD.begin(10)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
myFile = SD.open("test.txt", FILE_WRITE);
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
display.clearDisplay();
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
while (myFile.available()) {
Serial.write(myFile.read());
display.setCursor(0,0);
display.print(myFile.read());
display.display();
delay(5000);
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop() {
// put your main code here, to run repeatedly:
}
Code gets stuck at OLED initialization as mentiontioned above. If I replace these lines:
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // CODE GETS STUCK HERE. DISPLAY NEVER INITIALISES
}
To this:
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
I have run I2C scanner code on OLED so the address "0x3C" is correct.
The OLED still doesn't work and SD card initialises but Arduino is writing wrong data to TXT file on SD card like this:
teóting 1,à2, ó®
Instead of:
testing 1, 2, 3.
I have also tried using U8G2 library's sketches with SD card in case Arduino was running out of RAM but it still doesn't work. I have also changed SD chip select to Arduino digital pin 4 but still same results.
On browsing and experimenting more,I found MISO OR MOSI PIN of SD maybe interfering with SDA/SCL pins of OLED. Maybe wiring needs to change.
ANY SUGGESTIONS?
(I had the same issue) Just posting the suggestions of the comments as an answer, all credit to #gre_gor and #datafiddler for discovering this:
Both libraries together run out of RAM (main memory).
From my testing, the SD library might continue to work if it is initialized first in setup(). The solution is to use the U8G2 OLED driver, which is much more memory economic. The driver is also in the official Arduino library directive, so you can install and use it directly from the IDE.

How to edit library to use with Arduino DUE?

I want to add Arduino DUE in this code.
// Arduino Uno, Duemilanove, LilyPad, etc
//
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
#define ALTSS_USE_TIMER1
#define INPUT_CAPTURE_PIN 8 // receive
#define OUTPUT_COMPARE_A_PIN 9 // transmit
#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM
Code from library
The preprocessor for the Arduino Due is __SAM3X8E__. For example:
// Arduino Uno, Duemilanove, LilyPad, etc
//
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
#define ALTSS_USE_TIMER1
#define INPUT_CAPTURE_PIN 8 // receive
#define OUTPUT_COMPARE_A_PIN 9 // transmit
#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM
//
// Arduino Due
//
#elif defined(__SAM3X8E__)
// define or do your stuff

Nodemcu 1.0 with arduino ide, collaborator cannot compile sketch but i can

We are making a weather station project at our school together with my teammate, both are using windows pc:s with arduino ide to program Nodemcu 1.0.
This sketch compiles without trouble on my pc with installed libraries (adafruit dht library 1.3.0 and adafruit unified sensor library 1.0.2).
Teammate reports of error when compiling:
\Documents\Arduino\libraries\Adafruit_Sensor-1.0.1\Adafruit_Sensor.cpp:2:26: fatal error: avr/pgmspace.h: No such file or directory
#include <avr/pgmspace.h>
^
compilation terminated.
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
we have compared libraries and both should have the same libraries installed.
#include "DHT.h"
#define DS18B20pin 4 //määritetään DS18B20 -sensorin datapin. Nodemcu pin D2 = GPIO 04
#define DHTPIN 5 //määritetään DHT11-sensorin datapin. Nodemcu pin D1 = GPIO 05.
#define LDRpin A0 //määritetään LDR-vastukselle A0 -pinni.
#define DHTTYPE DHT11 //määrittää DHT-sensorisarjasta että on DHT11 käytössä.
int DHTvalue; //DHT11 - Suhteellinen ilmankosteus prosentteina
float DSvalue; //DS18B20 - Lämpötila celciusasteina
int LDRvalue; //LDR - Valon määrä prosentteina
DHT dht(DHTPIN, DHTTYPE);
void setup() {
pinMode(DS18B20pin, INPUT);
Serial.begin(115200); //alustetaan sarjaportti ja nopeus.
dht.begin(); //alustetaan dht-kirjastosta sensori.
}
void loop() {
delay(2000); //DHT11 vaatii vähintään 2 sekunnin delayn lukujen välillä.
//luetaan valon määrä LDR-vastukselta ja tulostetaan se sarjaportille.
int ldr_lukema = analogRead(LDRpin);
LDRvalue = ldr_lukema * (100 / 1023.0); //muutetaan 0-1023 arvoinen analogiarvo prosenteiksi 0-100.
Serial.print("Valon määrä(%): ");
Serial.println(LDRvalue);
//Tarkistetaan että DHT11 lukemat ovat ok.
Serial.print("Ilmankosteusanturin tila: ");
int dht11_tila = dht.readHumidity();
if(isnan(dht11_tila)){
Serial.println("virhe");
}else{
Serial.println("OK");
}
Serial.print("Ilman suhteellinen kosteus(%): ");
Serial.println((float)dht.readHumidity());
Serial.println("-----------------------------------------------");
}
The problem is your teammate is using a different version of the Adafruit Unified Sensor Driver library. As you can see from the error message:
\Documents\Arduino\libraries\Adafruit_Sensor-1.0.1\Adafruit_Sensor.cpp:2:26: fatal error: avr/pgmspace.h: No such file or directory
they are using version 1.0.1 and you are using 1.0.2. The unnecessary include of avr/pgmspace.h was removed between those two versions.

Resources