Skip to content

Commit

Permalink
Merge pull request #71 from Bfreak/master
Browse files Browse the repository at this point in the history
Added example to stream a file to the modem so it can be sent to FTP server
  • Loading branch information
lewisxhe authored Jun 1, 2024
2 parents 07ca739 + 553011e commit 2bc4e3f
Show file tree
Hide file tree
Showing 3 changed files with 323 additions and 0 deletions.
192 changes: 192 additions & 0 deletions examples/ModemFileUploadExample/Imagetofiletest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#include <Arduino.h>
#include "utilities.h" // Include the utilities header
#include <vector>
#include <SPI.h>
#include <FS.h>
#include <SD_MMC.h>
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialAT Serial1

// See all AT commands, if wanted
#define DUMP_AT_COMMANDS
#define TINY_GSM_MODEM_SIM7080
#include <TinyGsmClient.h>

#ifdef DUMP_AT_COMMANDS // if enabled it requires the streamDebugger lib
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif

#define XPOWERS_CHIP_AXP2101
#include "XPowersLib.h"
XPowersPMU PMU;

bool firstChunk = true;

#include <algorithm> // Include the <algorithm> header for the std::min function

const size_t bufferSize = 10240; // 10KB buffer size
uint8_t buffer[bufferSize];

void sendFileToModem(File file, const char* filename) {
modem.sendAT("+CFSTERM"); // Close FS in case it's still initialized
if (modem.waitResponse() != 1) {
Serial.println("Failed to terminate file system");
return;
}

modem.sendAT("+CFSINIT"); // Initialize FS
if (modem.waitResponse() != 1) {
Serial.println("Failed to initialize file system");
return;
}

// Get the total size of the file
size_t totalSize = file.size();
size_t alreadySent = 0;
bool firstChunk = true;

// Loop for sending chunks
while (totalSize > 0) {
// Determine the size of the next chunk to send
size_t chunkSize = std::min(totalSize, static_cast<size_t>(10000)); // Limit chunk size to 10,000 bytes

// Prepare the file upload command
String command = "+CFSWFILE=0,\"" + String(filename) + "\"," + String(firstChunk ? 0 : 1) + "," + String(chunkSize) + ",10000";
Serial.println(command); // For reference
modem.sendAT(command.c_str()); // Send file upload command
// if (modem.waitResponse(30000UL, "ERROR") == 1) { // Wait for modem confirmation
// Serial.println("Modem did not respond with DOWNLOAD");
// return;
// }

// Write the chunk of data to the modem
size_t bytesRead = file.read(buffer, std::min(chunkSize, bufferSize)); // Read chunkSize bytes from the file
if (bytesRead > 0) {
size_t bytesWritten = modem.stream.write(buffer, bytesRead); // Write the read data to the modem's stream
if (bytesWritten != bytesRead) {
Serial.println("Failed to write chunk to modem");
return;
}
alreadySent += bytesWritten;
totalSize -= bytesWritten;

Serial.printf("Sent %d bytes, %d bytes remaining\n", bytesWritten, totalSize);
} else {
Serial.println("Failed to read chunk from file");
return;
}

firstChunk = false; // Update the flag after the first chunk
}

Serial.println("File upload completed");

// Terminate file system after sending the file
modem.sendAT("+CFSTERM");
if (modem.waitResponse() != 1) {
Serial.println("Failed to terminate file system after sending the file");
return;
}
}




void setup() {
Serial.begin(115200);

// Start while waiting for Serial monitoring
while (!Serial);

delay(3000);

Serial.println();

/*********************************
* step 1 : Initialize power chip,
* turn on modem and gps antenna power channel
***********************************/
if (!PMU.begin(Wire1, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) {
Serial.println("Failed to initialize power.....");
while (1) {
delay(5000);
}
}
// Set the working voltage of the modem, please do not modify the parameters
PMU.setDC3Voltage(3000); // SIM7080 Modem main power channel 2700~ 3400V
PMU.enableDC3();

// Modem GPS Power channel
PMU.setBLDO2Voltage(3300);
PMU.enableBLDO2(); // The antenna power must be turned on to use the GPS function

// TS Pin detection must be disabled, otherwise it cannot be charged
PMU.disableTSPinMeasure();

/*********************************
* step 2 : start modemAT
***********************************/

Serial1.begin(115200, SERIAL_8N1, BOARD_MODEM_RXD_PIN, BOARD_MODEM_TXD_PIN);

pinMode(BOARD_MODEM_PWR_PIN, OUTPUT);
pinMode(BOARD_MODEM_DTR_PIN, OUTPUT);
pinMode(BOARD_MODEM_RI_PIN, INPUT);

int retry = 0;
while (!modem.testAT(1000)) {
Serial.print(".");
if (retry++ > 6) {
// Pull down PWRKEY for more than 1 second according to manual requirements
digitalWrite(BOARD_MODEM_PWR_PIN, LOW);
delay(100);
digitalWrite(BOARD_MODEM_PWR_PIN, HIGH);
delay(1000);
digitalWrite(BOARD_MODEM_PWR_PIN, LOW);
retry = 0;
Serial.println("Retry start modem .");
}
}

// Initialize SD card with specific pins
PMU.setALDO3Voltage(3300); // SD Card VDD 3300
PMU.enableALDO3();

// TS Pin detection must be disabled, otherwise it cannot be charged
PMU.disableTSPinMeasure();

SD_MMC.setPins(SDMMC_CLK, SDMMC_CMD, SDMMC_DATA); //set sdcard pin use 1-bit mode

if (!SD_MMC.begin("/sdcard", true)) {
Serial.println("Card Mount Failed");
while (1) {
delay(1000);
}

}

uint8_t cardType = SD_MMC.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD_MMC card attached");
while (1) {
delay(1000);
}
}

File imageFile = SD_MMC.open("/camimage.jpg");
if (imageFile) {
Serial.println("Image opened, sending!");
sendFileToModem(imageFile, "camimage.jpg");
imageFile.close();
} else {
Serial.println("Failed to open image file!");
}
}

void loop() {
}

Binary file added examples/ModemFileUploadExample/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
131 changes: 131 additions & 0 deletions examples/ModemFileUploadExample/utilities.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* @file utilities.h
* @author Lewis He ([email protected])
* @license MIT
* @copyright Copyright (c) 2022 Shenzhen Xin Yuan Electronic Technology Co., Ltd
* @date 2022-09-16
*
*/

#pragma once

//
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
// Ensure ESP32 Wrover Module or other board with PSRAM is selected
// Partial images will be transmitted if image exceeds buffer size
//
// You must select partition scheme from the board menu that has at least 3MB APP space.
// Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15
// seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well

// ===================
// Select camera model
// ===================
// #define LILYGO_ESP32S3_CAM_PIR_VOICE // Has PSRAM
#define LILYGO_ESP32S3_CAM_SIM7080G // Has PSRAM



// Set this to true if using AP mode
#define USING_AP_MODE true


// ===================
// Pins
// ===================
#ifdef I2C_SDA
#undef I2C_SDA
#endif

#ifdef I2C_SCL
#undef I2C_SCL
#endif


#if defined(LILYGO_ESP32S3_CAM_PIR_VOICE)

#define PWDN_GPIO_NUM (-1)
#define RESET_GPIO_NUM (17)
#define XCLK_GPIO_NUM (38)
#define SIOD_GPIO_NUM (5)
#define SIOC_GPIO_NUM (4)
#define VSYNC_GPIO_NUM (8)
#define HREF_GPIO_NUM (18)
#define PCLK_GPIO_NUM (12)
#define Y9_GPIO_NUM (9)
#define Y8_GPIO_NUM (10)
#define Y7_GPIO_NUM (11)
#define Y6_GPIO_NUM (13)
#define Y5_GPIO_NUM (21)
#define Y4_GPIO_NUM (48)
#define Y3_GPIO_NUM (47)
#define Y2_GPIO_NUM (14)

#define I2C_SDA (7)
#define I2C_SCL (6)

#define PIR_INPUT_PIN (39)
#define PMU_INPUT_PIN (2)


#define IIS_WS_PIN (42)
#define IIS_DIN_PIN (41)
#define IIS_SCLK_PIN (40)

#define BUTTON_CONUT (1)
#define USER_BUTTON_PIN (0)
#define BUTTON_ARRAY {USER_BUTTON_PIN}


#define BOARD_CAM_1V8_CHANNEL 1
#define BOARD_CAM_3V0_CHANNEL 1
#define BOARD_CAM_2V8_CHANNEL 1
#define BOARD_MIC_CHANNEL 2
#define BOARD_PIR_CHANNEL 2

#define USING_MICROPHONE


#elif defined(LILYGO_ESP32S3_CAM_SIM7080G)


#define PWDN_GPIO_NUM (-1)
#define RESET_GPIO_NUM (18)
#define XCLK_GPIO_NUM (8)
#define SIOD_GPIO_NUM (2)
#define SIOC_GPIO_NUM (1)
#define VSYNC_GPIO_NUM (16)
#define HREF_GPIO_NUM (17)
#define PCLK_GPIO_NUM (12)
#define Y9_GPIO_NUM (9)
#define Y8_GPIO_NUM (10)
#define Y7_GPIO_NUM (11)
#define Y6_GPIO_NUM (13)
#define Y5_GPIO_NUM (21)
#define Y4_GPIO_NUM (48)
#define Y3_GPIO_NUM (47)
#define Y2_GPIO_NUM (14)

#define I2C_SDA (15)
#define I2C_SCL (7)

#define PMU_INPUT_PIN (6)

#define BUTTON_CONUT (1)
#define USER_BUTTON_PIN (0)
#define BUTTON_ARRAY {USER_BUTTON_PIN}

#define BOARD_MODEM_PWR_PIN (41)
#define BOARD_MODEM_DTR_PIN (42)
#define BOARD_MODEM_RI_PIN (3)
#define BOARD_MODEM_RXD_PIN (4)
#define BOARD_MODEM_TXD_PIN (5)

#define USING_MODEM

#define SDMMC_CMD (39)
#define SDMMC_CLK (38)
#define SDMMC_DATA (40)
#else
#error "Camera model not selected"
#endif

0 comments on commit 2bc4e3f

Please sign in to comment.