Transfer data from Arduino Nano 33 IoT to PC via Bluetooth

Hello,
I recorded the sensor data of the BME280 and an RTC module and saved it to a file on an SD card. Now I want to transfer this file to a PC via Bluetooth or WLAN. Can someone help me how to do this? That's my code so far.

I use an Arduino Nano 33 IoT, Adafruit BME 280, DS1307 (Elegoo), HW-704 (Micro-SD-Shield), 16GB SD-Card

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <DS3231.h>
#include "RTClib.h"


#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

unsigned long delayTime;
bool start = true;
File myFile;
String Temperature, Pressure, Altitude, Humidity, Messung;
String Date; 
RTC_DS1307 rtc;

//Adafruit BME 280
Adafruit_BME280 bme; // I2C

// Real Time Clock 
DS3231 clock;
RTCDateTime dt;


void setup() {
  
  Serial.begin(57600);
  
//*RTC Initialisierung*
  if (! rtc.begin()) 
  {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }
  if (! rtc.isrunning()) 
  {
    Serial.println("RTC is NOT running, let's set the time!");
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
 
  clock.begin();
  //Send sketch compiling time to Arduino
  clock.setDateTime(__DATE__,__TIME__); 

  //*BME280 Initialisierung*
  if (! bme.begin(0x77, &Wire)) 
  {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
  }

    bme.setSampling(Adafruit_BME280::MODE_NORMAL,
                    Adafruit_BME280::SAMPLING_X8,  // temperature
                    Adafruit_BME280::SAMPLING_X16, // pressure
                    Adafruit_BME280::SAMPLING_X1,  // humidity
                    Adafruit_BME280::FILTER_X8,
                    Adafruit_BME280::STANDBY_MS_0_5 );

 //*SD card Initialisierung*
    while (!Serial)
    {
      Serial.print("Initializing SD card...");

      if (!SD.begin(10)) 
      {
        Serial.println("initialisation failed!");
        while(1);
      }
      
      Serial.println("inistalisation done");
    }
   myFile = SD.open("Messung.txt", FILE_WRITE);
   
   if (myFile)
   {
    myFile.println("Date | Time | Temperature (°C) | Pressure (hPa) | Humidity (%) \r\n");
    myFile.close();
   }
   
   else 
   {
    Serial.println("error opening Messung.txt");
   }
   delayTime = 5000;
}

void loop() 
{
 if (start == true)
  {
    delay(1000);
    Serial.print("Date | Time | Temperature | Pressure | Humidity");
    start = false;
  }

  // Only needed in forced mode! In normal mode, you can remove the next line.
  bme.takeForcedMeasurement(); // has no effect in normal mode
  printRTC();
  printBME280();
  
  delay(delayTime); 
}


void printRTC()
{
  DateTime time = rtc.now();
  Serial.print (String("DateTime::TIMESTAMP_DATE:\t")+ time.timestamp(DateTime::TIMESTAMP_DATE));
  Serial.print(String("DateTime::TIMESTAMP_TIME:\t")+ time.timestamp(DateTime::TIMESTAMP_TIME));

  Serial.println("\n");
  Serial.println("Beginne zu speichern");

  myFile = SD.open("Messung.txt", FILE_WRITE);
if(myFile)
  {
  myFile.print(time.timestamp(DateTime::TIMESTAMP_DATE));
  myFile.print(" | ");
  myFile.print(time.timestamp(DateTime::TIMESTAMP_TIME));
  myFile.print(" | ");
  myFile.close();
  Serial.println("gespeichert");
  }
  else
  {
    Serial.println("error opening Messung.txt nach RTC");
  }
}
  
void printBME280() 
{

  String Temperature = String(bme.readTemperature(), 2);
  String Pressure = String(bme.readPressure() / 100.0F,2);
  String Humidity = String(bme.readHumidity(),2);

  Messung = Temperature + " | " + Pressure + " | " + Humidity;
  Serial.println("Save Sensordata");
  Serial.println(Messung);

  myFile = SD.open("Messung.txt", FILE_WRITE);
  if(myFile) 
  {
    Serial.println("Writing to Messung.txt...");
    myFile.print(Messung);
    myFile.print("\n");
    myFile.close();
    Serial.println("done");
  }
  else
  {
    Serial.println("error opening Messung.txt nach Sensor");
  }
}

There are lots of options available.

What is the set up for the receiving machine? E.g., is it running a web or (S)FTP server, can you open a Bluetooth serial connection, etc.

Also, do you really want to receive a file, or would a stream of data be more convenient?

It should be said that the system runs autonomously. It should collect data for 2 months on a transport, then the data should be transmitted with Bluetooth. Which variant would be best suited for this?

Okay, then storing it in a file first makes a lot of sense.

Will it be the board or the PC that initiates the transfer?

My idea would be to connect to the PC via bluetooth to the microcontroller and then download or send the file

And what will the trigger be? A button press or something?

You could also consider setting up a serial over bluetooth connection, send a command from the PC to initiate the transfer after which the board sends its data (either via serial, or posting it to a webserver, or FTP server or something like that).

Alternatively, you could run a webserver on the board, which allows you to fetch the data via your browser.

It would be nice to know how large these files are.

Sending a command with the PC to get the data would be a great idea. But then a program would be necessary or how does it work?

Thanks for your help jfjlaros :slight_smile:

A small Python script should do the trick if you know how to set up serial over bluetooth on your PC.

Maybe there are ways to export the whole filesystem and mount it as a share on your PC, it would be good to search for that first.

[edit]

A quick search for exporting a filesystem did not give me any useful results. If writing a program for the PC is not an option, then perhaps using WiFi and running a webserver on the board is the easiest solution.

This should all be pretty straightforward, is certainly in common use, and re-inventing the wheel is definitely not required.

The sensor data can be sent constantly each time round the loop via Bluetooth for reception by PC, phone etc., if and as you like, using any terminal programme. I use RealTerm on PC and Bluetooth Graphics terminal on the phone.

Serial.print is all the Arduino code you need for this.

Nano can also await command to send an entire file as it accumulates. The obvious way to do this is to check for input via Bluetooth, e.g. the file name you want.

The FileDump example included in the SD examples in the IDE should be all you need to do this.

You can probably send the data direct to Excel. PLX-DAQ version 2 - now with 64 bit support! (and further new features)

I have no experience with Phyton and unfortunately do not know how to write such a program to get a serial connection via Bluetooth.
If I have understood it correctly, I use the example of Arduino "DumpFile" to see if a file exists and output the content via the serial port.

Step 1: Establish a Bluetooth connection between Nano and PC.
Step 2: Set up a serial interface with a terminal program.
Step 3: By entering "file name" the file is searched for on the SD card, if available, the content is output via the serial interface.

Is it right?

Yes, that is more or less what I suggested.

The example works with a fixed file name, but what you suggest should be easy to add.

If your terminal program offers the possibility to write the results to a file, you should be good to go without the need for any additional script on your PC.

Fartarsing around with Python is the last thing you need to do. You need no more programming skills than you need to send data to the serial monitor - which I assume you are already familiar with. The "serial connection" is done with the terminal programme - which you do not have to write yourself.

You are making too much of what you have to do

Step 1: Establish Bluetooth connection between PC (master) and Nano (slave)
You do this at the PC - it is procedure, not programming.
You never have to use Arduino to establish the link, unless perhaps, you want to do it automatically.

Step 2: Use the terminal on the PC to communicate. The receipt of the steady data stream confirms it. "Set up a serial interface" is just pompous technobabble

Step 3. Yes, you send the filename from the PC terminal. The "trigger" for the dumpfile subroutine is the receipt of the input from PC. You do need to ensure that you never send anything other than a legitimate filename, unless you have programmed Arduino accordingly. In my case, I start a new file at midnight and use the date as the name, so I just send the date I need - MMDD.

Note particularly that I am referring to using Bluetooth "classic" i.e. HC-0x. I'm not familiar with the Bluetooth on your Nano. If it is only capable of using BLE, it probably means more programming than I am suggesting, but the principle is essentially the same, and this is not a reason for passing BLE up and using Bluetooth classic.

The partial loop and related subroutines might be useful.

void loop() {
   GetClock();
  if (today != day)
  {
   today = day;
   getFileName(); 
  }
  
    while (Serial.available()) 
  {
    delay(3);  
    char c = Serial.read();
    readString += c; 
  }// end while

  if (readString.length() >0) 
  {  
    getDump();   
   readString="";  
   } // end if
ladedah to end of loop

void getFileName(){
sprintf(filename, "%02d%02d%02d.csv", year, month, day);
}

void GetClock(){
  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);

  second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  day = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}

void getDump() {
   stringSix = "2015" + readString + ".csv";
   stringSix.toCharArray(charBuf, 15);  
     Serial.println("");
     Serial.println(charBuf);
  File dumpFile = SD.open(charBuf);
  if (dumpFile) 
  {
    lcd.clear();
      lcd.setCursor (0,1);
      lcd.println("DUMP FROM ");
      lcd.setCursor (0,2);
      lcd.println(charBuf);
    while (dumpFile.available())
    {
      Serial.write(dumpFile.read());
    }
    dumpFile.close();
  }  
}


Note that the terminal records all traffic and there is no problem identifying a dump from a datastream!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.