Hi all. I'm currently trying to figure out my problem.
The code is meant to red a data string from another UNO via the RX pin then save the data string to SD.
The code and UNO also control the power button and shutter button on a cheap action cam.
Everything above works as it should with no problems.
The next part I need to implement is to send a string of data via a Rockblock 9603. As I am only just starting to integrate the Modem into the code I thought id start with the basicSend example on the IridiumSBD library.
I can get most of it to work until I ask the modem to //Send the message. At which point my serial console gives me "Error opening file for writing!"
If I comment that whole section for //Send the message then it works again.
Thinking its some sort of conflict but i cant get y head around it.
Any help appreciated.
#include <SD.h>
#include <SPI.h>
#include <IridiumSBD.h>
#include <SoftwareSerial.h>
// Pins for Camera control
#define CamPower_PIN 8
#define CamPhoto_PIN 9
// Variables for modem
#define DIAGNOSTICS true // Change this to see diagnostics
SoftwareSerial ss(6, 7);
IridiumSBD modem(ss, 5);
// Variables for Camera state machine
unsigned long previousMillis = 0;
unsigned long interval = 0; // Initialize with 0 to start immediately
int state = 0;
unsigned long previousHourMillis = 0;
unsigned long hourInterval = 50000; //
bool isCameraRunning = false; // Flag to control camera cycle execution
unsigned long previousModemMillis = 0;
unsigned long modemInterval = 50000; //
bool isModemRunning = false; // Flag to control modem cycle execution
// SD card settings
const int chipSelect = 4; // SD card CS pin
File dataFile;
void setup() {
// Initialize Serial communication for both RX and debugging at 115200 baud
Serial.begin(115200);
ss.begin(19200);
// Initialize Camera control pins
pinMode(CamPower_PIN, OUTPUT);
pinMode(CamPhoto_PIN, OUTPUT);
// Initialize SD card
if (!SD.begin(chipSelect)) {
Serial.println("SD card initialization failed!");
return;
}
Serial.println("SD card initialized.");
// Begin satellite modem operation
int signalQuality = -1;
int err;
Serial.println("Starting modem...");
err = modem.begin();
Serial.println("Modem initialised");
delay(1000);
modem.sleep();
if (err != ISBD_SUCCESS) {
Serial.print("Begin failed: error ");
Serial.println(err);
if (err == ISBD_NO_MODEM_DETECTED)
Serial.println("No modem detected: check wiring.");
}
}
void runModemCycle() {
unsigned long currentMillis = millis();
int signalQuality = -1;
int err;
modem.begin();
Serial.println("MODEM AWAKE");
err = modem.getSignalQuality(signalQuality);
if (err != ISBD_SUCCESS) {
Serial.print("SignalQuality failed: error ");
Serial.println(err);
return;
}
Serial.print("On a scale of 0 to 5, signal quality is currently ");
Serial.print(signalQuality);
Serial.println(".");
// Send the message
Serial.print("Trying to send the message. This might take several minutes.\r\n");
err = modem.sendSBDText("Hello, world!");
if (err != ISBD_SUCCESS)
{
Serial.print("sendSBDText failed: error ");
Serial.println(err);
if (err == ISBD_SENDRECEIVE_TIMEOUT)
Serial.println("Try again with a better view of the sky.");
}
else
{
Serial.println("Hey, it worked!");
}
}
void runCameraCycle() {
unsigned long currentMillis = millis();
switch (state) {
case 0: // Power on camera
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPower_PIN, HIGH);
Serial.println("cam power high");
previousMillis = currentMillis;
interval = 3000; // Wait for 3 seconds
state = 1;
}
break;
case 1: // Power off camera after 3 seconds
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPower_PIN, LOW);
previousMillis = currentMillis;
interval = 5000; // Wait for 5 seconds before next action
state = 2;
}
break;
case 2: // Switch to photo mode
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPower_PIN, HIGH);
delay(300); // Short delay
digitalWrite(CamPower_PIN, LOW);
Serial.println("Switching camera mode");
previousMillis = currentMillis;
interval = 1000; // Wait 1 second before taking a photo
state = 3;
}
break;
case 3: // Take one photo
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPhoto_PIN, HIGH);
delay(100); // Short delay for photo trigger
digitalWrite(CamPhoto_PIN, LOW);
Serial.println("took a photo");
previousMillis = currentMillis;
interval = 1000; // Wait 1 second after taking the photo
state = 4;
}
break;
case 4: // Switch to photo mode again
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPower_PIN, HIGH);
delay(300);
digitalWrite(CamPower_PIN, LOW);
Serial.println("Switching camera mode");
previousMillis = currentMillis;
interval = 3000; // Wait 3 seconds
state = 5;
}
break;
case 5: // Repeat the switching action
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPower_PIN, HIGH);
delay(300);
digitalWrite(CamPower_PIN, LOW);
Serial.println("Switching camera mode");
previousMillis = currentMillis;
interval = 3000; // Wait 3 seconds
state = 6;
}
break;
case 6: // Switch to video mode
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPower_PIN, HIGH);
delay(300);
digitalWrite(CamPower_PIN, LOW);
Serial.println("video mode");
previousMillis = currentMillis;
interval = 1000; // Wait 1 second before taking a video
state = 7;
}
break;
case 7: // Start video recording (simulated by a photo action here)
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPhoto_PIN, HIGH);
delay(100);
digitalWrite(CamPhoto_PIN, LOW);
Serial.println("taking a 20s video");
previousMillis = currentMillis;
interval = 20000; // 20 seconds for video recording
state = 8;
}
break;
case 8: // Power off after video recording
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPower_PIN, HIGH);
Serial.println("cam power high");
previousMillis = currentMillis;
interval = 3000; // Wait 3 seconds before powering off
state = 9;
}
break;
case 9: // Final power off
if (currentMillis - previousMillis >= interval) {
digitalWrite(CamPower_PIN, LOW);
Serial.println("cam off");
previousMillis = currentMillis;
interval = 3000; // Wait before resetting the cycle (optional)
state = 0; // Reset to initial state
isCameraRunning = false; // Stop camera cycle
}
break;
}
}
void logDataToSDCard() {
// Check if there's any incoming data on the Serial (RX pin 0)
if (Serial.available()) {
String incomingData = Serial.readStringUntil('\n'); // Read until newline
// Save the data to SD card
dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
// Serial print the data being saved
Serial.print("String saved to SD card: ");
Serial.println(incomingData); // Print the incoming data
// Write the incoming data to the file
dataFile.println(incomingData);
// Close the file
dataFile.close();
} else {
Serial.println("Error opening file for writing!");
}
}
}
void loop() {
unsigned long currentMillis = millis();
// Check if an hour has passed and the camera cycle is not already running
if (!isModemRunning && (currentMillis - previousModemMillis >= modemInterval)) {
isModemRunning = true; // Start camera cycle
previousModemMillis = currentMillis;
Serial.println("Starting modem cycle...");
}
// If camera cycle is running, continue to execute the state machine
if (isModemRunning) {
runModemCycle();
}
// Check if an hour has passed and the camera cycle is not already running
if (!isCameraRunning && (currentMillis - previousHourMillis >= hourInterval)) {
isCameraRunning = true; // Start camera cycle
previousHourMillis = currentMillis;
Serial.println("Starting camera cycle...");
}
// If camera cycle is running, continue to execute the state machine
if (isCameraRunning) {
runCameraCycle();
}
// Continuously log incoming data to SD card
logDataToSDCard();
}
```**strong text**