SD.remove() is not removing a file on Arduino C++ - c++

I have two sketches I am running on an Arduino Uno. The first one dumps a file to the serial if it exists. This is one of the examples that comes with the Arduino, but I've modified it as such:
/*
SD card file dump
This example shows how to read a file from the SD card using the
SD library and send it over the serial port.
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
Created 22 December 2010 by Limor Fried
Modified 9 Apr 2012 by Tom Igoe
This example code is in the public domain.
*/
#include <SD.h>
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // Wait for serial port to connect. Needed for Leonardo only.
}
Serial.print("Initializing SD card...");
// Make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// See if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// Don't do anything more:
return;
}
Serial.println("card initialized.");
// Open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt");
// If the file is available, write to it:
if (dataFile) {
while (dataFile.available()) {
Serial.write(dataFile.read());
}
dataFile.close();
}
// If the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
void loop()
{
}
My other sketch is supposed to remove a file. When I run this remove sketch it says there is no file found. Yet I can continually run the above sketch and dump the contents to the serial. My remove sketch is as follows:
#include <SD.h>
const int chipSelect = 4;
void setup(){
Serial.begin(115200);
Serial.print("Initializing SD card...");
// Make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
if(SD.exists("datalog.txt"))
{
SD.remove("datalog.txt");
Serial.println("file removed");
}
else
{
Serial.println("no file to remove");
}
}
void loop(){
}
Am I missing something here?
Just after posting this I realized I was not making this remove sketch fault tolerant and added the following code after the pinmode line:
// See if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
Thus the new remove sketch was as follows:
#include <SD.h>
const int chipSelect = 4;
void setup(){
Serial.begin(115200);
Serial.print("Initializing SD card...");
// Make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// See if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// Don't do anything more:
return;
}
Serial.println("card initialized.");
if(SD.exists("datalog.txt"))
{
SD.remove("datalog.txt");
Serial.println("file removed");
}
else
{
Serial.println("no file to remove");
}
}
void loop(){
}
Upon running that sketch it now removes the files. Why is it that new version works but the old one did not?

Adding SD.begin() doesn't make it fault tolerant. It initializes the library. You need to call that before calling other functions. From the Reference:
begin() Initializes the SD library and card. This begins use of the
SPI bus (digital pins 11, 12, and 13 on most Arduino boards; 50, 51,
and 52 on the Mega) and the chip select pin, which defaults to the
hardware SS pin (pin 10 on most Arduino boards, 53 on the Mega).

Related

LoRa communication between ESP8266 and RPi 3B+

I have an ESP8266 and a RPI 3B+ both equipped with LoRa-02 (SX1278) modules. I'm trying to send a packet from the ESP to the RPi, but it's not working.
Please consider the following code snippet on ESP8266:
main.cpp
#include "loRaComms.h"
void setup() {
// sender
Serial.begin(115200);
initLoRa(434800000);
}
void loop() {
// sender
brodcastBuffer();
delay(1000);
}
loRaComms.cpp
#include <LoRa.h>
void initLoRa(int freq) {
LoRa.setPins(Lora_NSS, Lora_RESET, Lora_DIO0);
LoRa.setFrequency(freq);
LoRa.setSignalBandwidth(62500);
LoRa.setSpreadingFactor(12);
LoRa.setCodingRate4(8);
LoRa.setGain(0);
LoRa.setPreambleLength(6);
if (!LoRa.begin(freq)) {
// initialize ratio at 915 MHz 433E6 - Asia, 866E6 - Europe, 915E6 - North America
Serial.println("LoRa init failed.");
} else {
Serial.println("LoRa init succeeded.");
}
}
void brodcastBuffer() {
LoRa.beginPacket(); // start packet
LoRa.print("hello!");
LoRa.endPacket();
}
I have no problem with the ESP8266 code. I have tested this code with 2 ESP8266, one sender and one receiver, everything is working fine!
Now let's see the RPi 3B+ code. I have used [this repository][1] with its own sample code as follows:
void * rx_f(void *p) {
rxData *rx = (rxData *)p;
printf("rx done \n");
printf("CRC error: %d\n", rx->CRC);
printf("Data size: %d\n", rx->size);
printf("string: %s\n", rx->buf); // Data we've received
printf("RSSI: %d\n", rx->RSSI);
printf("SNR: %f\n", rx->SNR);
free(p);
return NULL;
}
int main() {
LoRa_ctl modem;
// See for typedefs, enumerations and there values in LoRa.h header file
modem.spiCS = 0; // Raspberry SPI CE pin number
modem.rx.callback = rx_f;
modem.eth.preambleLen = 6;
modem.eth.bw = BW62_5; // Bandwidth 62.5KHz
modem.eth.sf = SF12; // Spreading Factor 12
modem.eth.ecr = CR8; // Error coding rate CR4/8
modem.eth.freq = 434800000; // 434.8MHz
modem.eth.resetGpioN = 27; // GPIO4 on lora RESET pin
modem.eth.dio0GpioN = 17; // GPIO17 on lora DIO0 pin to control Rxdone and Txdone interrupts
modem.eth.outPower = OP20; // Output power
modem.eth.powerOutPin = PA_BOOST; // Power Amplifier pin
modem.eth.AGC = 1; // Auto Gain Control
modem.eth.OCP = 240; // 45 to 240 mA. 0 to turn off protection
modem.eth.implicitHeader = 0; // Explicit header mode
modem.eth.syncWord = 0x12;
printf("%d\n", modem.eth.bw);
printf("%d\n", modem.eth.ecr);
// For detail information about SF, Error Coding Rate, Explicit header, Bandwidth, AGC, Over current protection and other features refer to sx127x datasheet https:// www.semtech.com/uploads/documents/DS_SX127$
LoRa_begin(&modem);
LoRa_receive(&modem);
while (1) {
usleep(200000);
}
printf("end\n");
LoRa_end(&modem);
}```
But I can't receive anything on RPi. I also tested the ping pong sample on two RPi 3 and it didn't work.
Did I miss something here? I'm open to use any alternative library on RPi3, but I can only use C/C++ libraries. I've used the following pins:
raspi LoRa
GPIO27, pin13 RESET
GPIO17, pin 11 DIO0
MOSI (GPIO10, pin 19) MOSI
MISO (GPIO9, pin 21) MISO
CLK (GPIO11, pin 23) SCK
SPI_CE0 (GPIO8, pin 24) NSS
[1]: https://%20github.com/YandievRuslan/sx1278-LoRa-RaspberryPi.git
You can check your pin connection
The PI 3 MISO is GPIO09 and MOSI is GPIO10.
So you need change the pin connection to the following
raspi LoRa
MOSI (GPIO10, pin 19) MISO
MISO (GPIO9, pin 21) MOSI
Here is the introduction of SPI MOSI and MISO
https://www.analog.com/en/analog-dialogue/articles/introduction-to-spi-interface.html

How would I get the nrFToolbox for BLE app to use Arduino code written using the ArduinoBLE library?

For reference, I am using the Arduino Nano 33 BLE Sense board.
At the moment, I can get the nrFToolbox app to recognize the board as a Bluetooth device, but that's about it. I would like to able to use the app to get data about the temperature and display it.
#include <Arduino_LPS22HB.h> //Pressure sensor, documentation found on https://www.arduino.cc/en/Reference/ArduinoLPS22HB
#include <Arduino_HTS221.h> //Temperature sensor, documentation found on https://www.arduino.cc/en/Reference/ArduinoHTS221
#include <ArduinoBLE.h> //Bluetooth LE sensor, documentation found on https://www.arduino.cc/en/Reference/ArduinoBLE
// Service for the BLE module, using a 128-bit UUID.
BLEService TestService("32BC370F-88AF-4928-B8AB-9B56902FA670");
//TODO: BLE temperature characteristic
//TODO: BLE humidity characteristic
//TODO: BLE pressure characteristic
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); //Initialize the serial connection
while(!Serial); //Will pause until a serial connection is established.
if (!BARO.begin() ) { //Initialize the barometer
Serial.println("Unable to initialize the barometer, stopping.");
while (1);
}
if (!HTS.begin() ) { //Initialize the Temperature & Humidity sensor
Serial.println("Unable to initialize the temp/humidity sensor, stopping.");
while (1);
}
if (!BLE.begin() ) { //Initialize the bluetooth module
Serial.println("Unable to initialize the bluetooth module, stopping");
while (1);
}
/* Set a local name for the BLE device
This name will appear in advertising packets
and can be used by remote devices to identify this BLE device
The name can be changed but maybe be truncated based on space left in advertisement packet
*/
BLE.setLocalName("TestDevice");
BLE.setAdvertisedService(TestService); // add the service UUID
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("Temperature: ");
Serial.print(HTS.readTemperature(FAHRENHEIT));
Serial.print(" -- Humidity: ");
Serial.print(HTS.readHumidity() );
Serial.print(" -- Pressure: ");
Serial.println(BARO.readPressure() );
delay(1000);
}

How to operate sd module in esp32?

I am new using microcontrollers and I am testing the operation of the example code of the platformio id to create a file in an sd, but when I compile it after passing it to ESP32, it throws me the error that appears in the image "Make sure SD card lines have pull-up resistors in place esp32". Is it a code problem or do I need to add some resistance to the connection?
I leave an image of how it is connected
Thanks
/* SD card and FAT filesystem example.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_vfs_fat.h"
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#include "sdmmc_cmd.h"
static const char *TAG = "example";
// This example can use SDMMC and SPI peripherals to communicate with SD card.
// By default, SDMMC peripheral is used.
// To enable SPI mode, uncomment the following line:
// #define USE_SPI_MODE
// When testing SD and SPI modes, keep in mind that once the card has been
// initialized in SPI mode, it can not be reinitialized in SD mode without
// toggling power to the card.
#ifdef USE_SPI_MODE
// Pin mapping when using SPI mode.
// With this mapping, SD card can be used both in SPI and 1-line SD mode.
// Note that a pull-up on CS line is required in SD mode.
#define PIN_NUM_MISO 2
#define PIN_NUM_MOSI 15
#define PIN_NUM_CLK 14
#define PIN_NUM_CS 13
#endif //USE_SPI_MODE
void app_main(void)
{
ESP_LOGI(TAG, "Initializing SD card");
#ifndef USE_SPI_MODE
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
// To use 1-line SD mode, uncomment the following line:
// host.flags = SDMMC_HOST_FLAG_1BIT;
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
// GPIOs 15, 2, 4, 12, 13 should have external 10k pull-ups.
// Internal pull-ups are not sufficient. However, enabling internal pull-ups
// does make a difference some boards, so we do that here.
gpio_set_pull_mode(15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1- line modes
gpio_set_pull_mode(2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
gpio_set_pull_mode(4, GPIO_PULLUP_ONLY); // D1, needed in 4-line mode only
gpio_set_pull_mode(12, GPIO_PULLUP_ONLY); // D2, needed in 4-line mode only
gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); // D3, needed in 4- and 1-line modes
#else
ESP_LOGI(TAG, "Using SPI peripheral");
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
slot_config.gpio_miso = PIN_NUM_MISO;
slot_config.gpio_mosi = PIN_NUM_MOSI;
slot_config.gpio_sck = PIN_NUM_CLK;
slot_config.gpio_cs = PIN_NUM_CS;
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
#endif //USE_SPI_MODE
// Options for mounting the filesystem.
// If format_if_mount_failed is set to true, SD card will be partitioned and
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 5
};
// Use settings defined above to initialize SD card and mount FAT filesystem.
// Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function.
// Please check its source code and implement error recovery when developing
// production applications.
sdmmc_card_t* card;
esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set format_if_mount_failed = true.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%d). "
"Make sure SD card lines have pull-up resistors in place.", ret);
}
return;
}
// Card has been initialized, print its properties
sdmmc_card_print_info(stdout, card);
// Use POSIX and C standard library functions to work with files.
// First create a file.
ESP_LOGI(TAG, "Opening file");
FILE* f = fopen("/sdcard/hello.txt", "w");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
fprintf(f, "Hello %s!\n", card->cid.name);
fclose(f);
ESP_LOGI(TAG, "File written");
// Check if destination file exists before renaming
struct stat st;
if (stat("/sdcard/foo.txt", &st) == 0) {
// Delete it if it exists
unlink("/sdcard/foo.txt");
}
// Rename original file
ESP_LOGI(TAG, "Renaming file");
if (rename("/sdcard/hello.txt", "/sdcard/foo.txt") != 0) {
ESP_LOGE(TAG, "Rename failed");
return;
}
// Open renamed file for reading
ESP_LOGI(TAG, "Reading file");
f = fopen("/sdcard/foo.txt", "r");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
char line[64];
fgets(line, sizeof(line), f);
fclose(f);
// strip newline
char* pos = strchr(line, '\n');
if (pos) {
*pos = '\0';
}
ESP_LOGI(TAG, "Read from file: '%s'", line);
// All done, unmount partition and disable SDMMC or SPI peripheral
esp_vfs_fat_sdmmc_unmount();
ESP_LOGI(TAG, "Card unmounted");
}
enter image description here
enter image description here
"Make sure SD card lines have pull-up resistors in place." is the default error message when communication with the SD Card (module) does not work.
esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set format_if_mount_failed = true.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%d). "
"Make sure SD card lines have pull-up resistors in place.", ret);
}
return;
}
The information about the pull-up resistors is only a hint what might be wrong similar to: Maybe one of your wires is not connected correctly.
I had the same error when I tried that code using an SD-Card module with SPI connection which I used previously with Arduino.
After trying lots of things and looking at info all over the internet it seems to me that this never worked with SPI and an SD-Card module which uses SPI. I remember I found info like "this will be implemented later" but I don't remember where I read that.
Later I found there are other SD-Card modules which don't use SPI.
I used this one and it worked.
https://www.ebay.com/itm/9-Pin-Micro-SD-TF-Card-Reader-Read-Write-Module-Storage-Board-Memory-Arduino/401316600781
This is not connected with SPI and that option has to be selected in the code here:
// This example can use SDMMC and SPI peripherals to communicate with SD card.
// By default, SDMMC peripheral is used.
// To enable SPI mode, uncomment the following line:
//#define USE_SPI_MODE
And later in the code there is this section:
// To use 1-line SD mode, uncomment the following line:
host.flags = SDMMC_HOST_FLAG_1BIT;
I was able to get it running by using the 1BIT mode with above module.
I didn't get it running using all connections (I think that is called SD Mode or 1 Line SD Mode).

Write from Serial Port to SD card

I am trying to write from the Serial Port to an SD Card in my Arduino Mega 2560, using a card module.
I want to be able to write in a txt file what I type in the serial com.
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.print("This is a test and should be ignored");
if (!SD.begin(chipSelect)) {
Serial.println("\nCard failed, or not present");
// don't do anything more:
return;
}
else{
Serial.println("\ncard initialized.");
}
}
void loop() {
// put your main code here, to run repeatedly
File OpenFile = SD.open("test.txt", FILE_WRITE);
if(OpenFile and Serial.available());
{
OpenFile.println(Serial1.read());
OpenFile.close();
}
}
However a continous line of "-1" and "1", without the ", is written to the SD.
Yes, I am able to write to the SD card through other methods...
Cheers, PoP
I notice you are checking Serial.available() but using Serial1 to read from :)
As you have a Mega, you wouldn't get an error as there is Serial and Serial1. I'd say this is your culprit!
The Stream read function will return -1 when there is no data. Also you could lessen the load on your Arduino and do the operation all at once (not open/close for each byte) and purge all available data (Serial.read() only reads a single byte in case you did not know).
void loop() {
File OpenFile = SD.open("test.txt", FILE_WRITE);
if(OpenFile){
while(Serial.available()){
OpenFile.println(Serial.read());
}
OpenFile.close();
}
}
You may want to check if the SD lib supports appending by default or a flag like FILE_APPEND as you will overwrite the file on the next loop if more data becomes available (Serial data isn't instant, your code may loop while receiving the rest of the data).

Using SD.remove() and SD library in Arduino

I'm building a program which takes 10 measurements of an analog voltage on pin0 and is printing it to a log file. The issue I'm running into comes when I try to ensure that the file is blank. I am using SD.remove() in order to remove a previous logfile. When I do this, the new log file is never actually written to. When I remove the call to SD.remove(), the program works correctly. Is this some known bug in the SD library or is there some sneaky way around this?
The code is below.
#include <SD.h>
#define OUTPUT_PIN 9 //Using SparkFun MP3 shield
#define DEFAULT_OUTPUT 10
#define VOLTAGE_REF (5)
//Reads a voltage on pin0. by default, the reference voltage is set to 5 V, but
//it can be changed by changing VOLTAGE_REF.
void setup() {
Serial.begin(9600);
Serial.println("Program Initialized");
pinMode(DEFAULT_OUTPUT ,OUTPUT); //Needs to be on to use the library
pinMode(0, INPUT);
if (!SD.begin(OUTPUT_PIN)) {
//init error
Serial.println("Error initializing SD card. Reset the Arduino and try again");
return;
}
Serial.println("Card sucessfully initialized");
if (SD.exists("LOGFILE.LOG") {
SD.remove("LOGFILE.LOG"); //We don't want to use the same file <<THIS IS THE BUG?
}
delay(10); //Make sure changes are applied
File logFile = SD.open("ANALOG.LOG", FILE_WRITE); //Create a new one every time
if (!SD.exists("LOGFILE.LOG")) {
Serial.println("There was some error making a new instance of the logfile?");
delay(1000);
SD.open("ANALOG.LOG", FILE_WRITE);
}
int i;
if (logFile) {
for(i=0;i<10;i++) {
int j = 0;
char str[64];
Serial.print("Reading analog sensor value");
for(j=0;j<=i;j++) {
Serial.print(".");
}
Serial.println();
logFile.print("Read #");
logFile.print(i+1);
logFile.print(" : ");
logFile.print(doVoltageRead(0));
unsigned char l = logFile.println(" V");
if (!l)
Serial.println("No data written");
delay(500);
}
Serial.println("Done.");
logFile.close(); //Close the logfile
Serial.println("Data sucessfully written");
}
else {
//Couldn't create file
Serial.println("There was an error creating the logfile");
}
}
void loop() {
//We don't really need to do anything here
}
float doVoltageRead(int pin) {
int voltageRead = analogRead(pin);
double divisor = (voltageRead * 0.00097752);
float finalVoltage =(VOLTAGE_REF * divisor);
Serial.println(finalVoltage);
return finalVoltage;
}
So.. First you see if LOGFILE.LOG exists, if it does you delete ANALOG.LOG. Then you create ANALOG.LOG. After that you check if LOGFILE.LOG exists. If it doesn't, you print an error and open ANALOG.LOG.
What exactly is the purpose of LOGFILE.LOG? Shouldn't you just change LOGFILE to ANALOG?
I have found the source of the error. When I called if(SD.exists()) after opening a new logfile, the library didn't like that. I am assuming SD.exists() just checks if the address or object returned by open is NULL. However, calling it when the file is already open would cause some strange behaviors. After removing that call inside open, all is well. Thanks for all the suggestions!