Saving an image from ESP32-CAM to SD Card - image

I've try to save an image from ESP32-CAM to SD Card. After uploading the code, i opened the Serial Monitor at a baud rate of 115200, then pressed the ESP32-CAM reset button to turn on ESP32CAM, i got an error like the following. For your information, the memory was formatted to FAT32. Can anyone help?
This is the error output :
Card Mount Failed
#include "esp_camera.h"
#include "Arduino.h"
#include "FS.h" // SD Card ESP32
#include "SD_MMC.h" // SD Card ESP32
#include "soc/soc.h" // Disable brownour problems
#include "soc/rtc_cntl_reg.h" // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h> // read and write from flash memory
// define the number of bytes you want to access
#define EEPROM_SIZE 1
// Pin definition for CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
int pictureNumber = 0;
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
//Serial.setDebugOutput(true);
//Serial.println();
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Init Camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
//Serial.println("Starting SD Card");
if(!SD_MMC.begin()){
Serial.println("SD Card Mount Failed");
return;
}
uint8_t cardType = SD_MMC.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD Card attached");
return;
}
camera_fb_t * fb = NULL;
// Take Picture with Camera
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
return;
}
// initialize EEPROM with predefined size
EEPROM.begin(EEPROM_SIZE);
pictureNumber = EEPROM.read(0) + 1;
// Path where new picture will be saved in SD Card
String path = "/picture" + String(pictureNumber) +".jpg";
fs::FS &fs = SD_MMC;
Serial.printf("Picture file name: %s\n", path.c_str());
File file = fs.open(path.c_str(), FILE_WRITE);
if(!file){
Serial.println("Failed to open file in writing mode");
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.printf("Saved file to path: %s\n", path.c_str());
EEPROM.write(0, pictureNumber);
EEPROM.commit();
}
file.close();
esp_camera_fb_return(fb);
// Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
pinMode(4, INPUT);
digitalWrite(4, LOW);
rtc_gpio_hold_dis(GPIO_NUM_4);
delay(2000);
Serial.println("Going to sleep now");
delay(2000);
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void loop() {
}

This code works for me. I would suggest that you use a different memory card and if it still doesn't work then erase the flash memory of ESP32 cam.

Related

Issues getting Arduino program to run on ESP01s (ESP8266)

I am trying to create a server with a simple webpage using the ESP01s module. My pin connections are as follows:
ESP TX to Arduino Uno Tx pin
ESP RX to Arduino Uno Rx pin
ESP VCC to Uno 3.3V pin
ESP GND to Uno GND
ESP EN to Uno 3.3V through 10K resistor
I am using the Arduino IDE and serial to USB cable, when I run a blank program I can send AT commands to the ESP module with no issues.
However when I try to run a script to build and deploy the simple webpage, I either get one of two messages in the IDE serial monitor or nothing:
Unreadable characters - jibberish
Boot instructions
load 0x40100000, len 27728, room 16
tail 0
chksum 0x2a
load 0x3ffe8000, len 2124, room 8
tail 4
chksum 0x07
load 0x3ffe8850, len 9276, room 4
tail 8
chksum 0xba
csum 0xba
No output to serial monitor even though code uploads
This is my code:
#include <SoftwareSerial.h>
SoftwareSerial esp8266(0,1); // rx, tx;
#define serialCommunicationSpeed 115200
#define DEBUG true
void setup()
{
Serial.begin(serialCommunicationSpeed);
esp8266.begin(serialCommunicationSpeed);
InitWifiModule();
}
void loop() {
if (esp8266.available()) {
if (esp8266.find("+IPD,")) {
delay(1000);
int connectionId = esp8266.read() - 48;
String webpage = "<h1>Capstone Group 45: SolarFi</h1>";
String cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend += webpage.length();
cipSend += "\r\n";
sendData(cipSend, 1000, DEBUG);
sendData(webpage, 1000, DEBUG);
String closeCommand = "AT+CIPCLOSE=";
closeCommand += connectionId; // append connection id
closeCommand += "\r\n";
sendData(closeCommand, 3000, DEBUG);
}
}
}
String sendData(String command, const int timeout, boolean debug) {
String response = "";
esp8266.print(command);
long int time = millis();
while ((time + timeout) > millis()) {
while (esp8266.available()) {
char c = esp8266.read();
response += c;
}
}
if (debug) {
Serial.print(response);
}
return response;
}
void InitWifiModule() {
sendData("AT+RST\r\n", 2000, DEBUG);
sendData("AT+CWJAP=\"USERNAME\",\"PASSWORD\"\r\n", 2000, DEBUG);
delay(3000);
sendData("AT+CWMODE=1\r\n", 1500, DEBUG);
delay(1500);
sendData("AT+CIFSR\r\n", 1500, DEBUG);
delay(1500);
sendData("AT+CIPMUX=1\r\n", 1500, DEBUG);
delay(1500);
sendData("AT+CIPSERVER=1,80\r\n", 1500, DEBUG);
}

How to produce same mfcc result as librosa using aubio?

I am trying to calculate Mfcc feature in C++. And I found Aubio (https://github.com/aubio/aubio) but I cannot produce same result as Librosa of Python (this is important).
Librosa code:
X, sample_rate = sf.read(file_name, dtype='float32')
mfccs = librosa.feature.mfcc(y=X, sr=sample_rate, n_mfcc=40)
Aubio code:
#include "utils.h"
#include "parse_args.h"
#include <stdlib.h>
aubio_pvoc_t *pv; // a phase vocoder
cvec_t *fftgrain; // outputs a spectrum
aubio_mfcc_t * mfcc; // which the mfcc will process
fvec_t * mfcc_out; // to get the output coefficients
uint_t n_filters = 128;
uint_t n_coefs = 40;
void process_block (fvec_t *ibuf, fvec_t *obuf)
{
fvec_zeros(obuf);
//compute mag spectrum
aubio_pvoc_do (pv, ibuf, fftgrain);
//compute mfccs
aubio_mfcc_do(mfcc, fftgrain, mfcc_out);
}
void process_print (void)
{
/* output times in selected format */
print_time (blocks * hop_size);
outmsg ("\t");
/* output extracted mfcc */
fvec_print (mfcc_out);
}
int main(int argc, char **argv) {
int ret = 0;
// change some default params
buffer_size = 2048;
hop_size = 512;
examples_common_init(argc,argv);
verbmsg ("using source: %s at %dHz\n", source_uri, samplerate);
verbmsg ("buffer_size: %d, ", buffer_size);
verbmsg ("hop_size: %d\n", hop_size);
pv = new_aubio_pvoc (buffer_size, hop_size);
fftgrain = new_cvec (buffer_size);
mfcc = new_aubio_mfcc(buffer_size, n_filters, n_coefs, samplerate);
mfcc_out = new_fvec(n_coefs);
if (pv == NULL || fftgrain == NULL || mfcc == NULL || mfcc_out == NULL) {
ret = 1;
goto beach;
}
examples_common_process(process_block, process_print);
printf("\nlen=%u\n", mfcc_out->length);
del_aubio_pvoc (pv);
del_cvec (fftgrain);
del_aubio_mfcc(mfcc);
del_fvec(mfcc_out);
beach:
examples_common_del();
return ret;
}
Please help to obtain same result of Librosa or suggest any C++ library do this well.
Thanks
This might be what you are looking for: C Speech Features
The library is a complete port of python_speech_features to C and according to the documentation, you should be able to use it in a C++ projects. The results will not be the same of Librosa, here is why but you should be able to work with them.

ESP32 SDCARD speed issue

I am trying to use SD Card on Wrover kit but it seems that speed is the big issue on the board itself.
At first I wanted to download file from the net and save it to SDCARD but it took too long so to test it I've written a loop to save some chars into file and create ~1MB large file on a SDCARD and it takes forever.
What could be the cause that ~1MB file could be such a long task to do.
I have combined two examples into one to do the task.
Also I have commented everything and left just part with writing to file to demonstrate issue.
/* ESP HTTP Client 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.
*/
#define LOG_LOCAL_LEVEL ESP_LOG_ERROR
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "app_wifi.h"
#include "esp_http_client.h"
/* SD CARD */
#include "esp_vfs_fat.h"
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#include "sdmmc_cmd.h"
/* SD CARD */
#define USE_SPI_MODE
#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
//#define MAX_HTTP_RECV_BUFFER 512
#define MAX_HTTP_RECV_BUFFER 1024
static const char *TAG = "HTTP_CLIENT";
// ------------------ GLOBAL VARS -----------------------------
FILE *fp=NULL;
// ------------------ GLOBAL VARS -----------------------------
/* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem
The PEM file was extracted from the output of this command:
openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null
The CA root cert is the last cert given in the chain of certs.
To embed it in the app binary, the PEM file is named
in the component.mk COMPONENT_EMBED_TXTFILES variable.
*/
extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start");
extern const char howsmyssl_com_root_cert_pem_end[] asm("_binary_howsmyssl_com_root_cert_pem_end");
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
switch(evt->event_id) {
case HTTP_EVENT_ERROR:
ESP_LOGE (TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGE (TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGE (TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGE (TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGE (TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
if (!esp_http_client_is_chunked_response(evt->client)) {
// Write out data
// printf("%.*s", evt->data_len, (char*)evt->data);
if(fp == NULL){
fp = fopen("/sdcard/muzika.mp3","wb");
}
if(fp != NULL){
fwrite(evt->data,1,evt->data_len,fp);
ESP_LOGE (TAG, "---------- HTTP_EVENT_ON_DATA - WRITING TO SD CARD ----------");
}
}
break;
case HTTP_EVENT_ON_FINISH:
ESP_LOGE (TAG, "HTTP_EVENT_ON_FINISH");
fclose(fp);
fp = NULL;
break;
case HTTP_EVENT_DISCONNECTED:
ESP_LOGE (TAG, "HTTP_EVENT_DISCONNECTED");
break;
}
return ESP_OK;
}
static void http_download_chunk()
{
esp_http_client_config_t config = {
//.url = "http://httpbin.org/stream-bytes/8912",
.url = "http://www.theoctopusproject.com/mp3/whatthey.mp3",
.event_handler = _http_event_handler,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP chunk encoding Status = %d, content_length = %d",
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
}
esp_http_client_cleanup(client);
}
static void http_test_task(void *pvParameters)
{
app_wifi_wait_connected();
ESP_LOGI(TAG, "Connected to AP, begin http example");
http_download_chunk();
ESP_LOGI(TAG, "Finish http example");
vTaskDelete(NULL);
}
void app_main()
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// -- app_wifi_initialise();
/* SDCARD SETUP */
#ifndef USE_SPI_MODE
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
// 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();
// To use 1-line SD mode, uncomment the following line:
// slot_config.width = 1;
// 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,
.allocation_unit_size = 16 * 1024
};
// 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;
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 (%s). "
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(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_LOGE(TAG, "Opening file");
FILE* f = fopen("/sdcard/hello.txt", "w");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
// ------------------------ WRITE INTO FILE -------------------
int j=0;
for(int i = 0 ; i < 1048576 ; i++,j++){
//fprintf(f, "Hello %s!\n", card->cid.name);
fprintf(f, "X");
if(j > 1024){
vTaskDelay(3);
j = 0;
}
}
fclose(f);
ESP_LOGE(TAG, "File written");
// ------------------------ WRITE INTO FILE -------------------
//-- xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL);
//xTaskCreate(&http_test_task, "http_test_task", 16384, NULL, 5, NULL);
}
Your example is writing one byte at a time. That won't get you an accurate idea of how the overall speed of writing to the SD card - your code will spend a disproportionate amount of time processing the individual writes.
If you want to get a more accurate idea of how fast you can write to the card, try writing 1024 bytes (or even more) at a time. Benchmarks that measure maximum throughput and performance-sensitive applications will always write as much data as they can at a time in order to minimize the overhead of the write.
Also, don't use fprintf() if possible. It has extra overhead because it parses the format string. Try fwrite() - it will have less overhead and will give you a better idea of what you can expect in the best case.
Try something like this instead:
char *buf = malloc(1024);
if(buf) {
for(int i = 0; i < 1024; i++) {
fwrite(buf, 1, 1024, f);
vTaskDelay(3); // you'll speed this up if you can omit this
}
ESP_LOGE(TAG, "File written");
free(buf);
} else
ESP_LOGE(TAG, "malloc() failed");
fclose(f);

programming PIC32MX250F128B with Pickit3

I am successfully programming PIC32MX250F128B using Pickit3. I have written a code where, when I press a I am getting 100 data from vibration sensor. Now if I want to get another 100 data, either I have to disconnect and then reconnect the 10k ohm pull up resistor connected to MCLR pin or have to run the program again.
Is there any other way I can reset the pickit?
Here is the code I am using:
#include <p32xxxx.h> // include chip specific header file
#include <plib.h> // include peripheral library functions
// Configuration Bits
#pragma config FNOSC = FRCPLL // Internal Fast RC oscillator (8 MHz) w/ PLL
#pragma config FPLLIDIV = DIV_2 // Divide FRC before PLL (now 4 MHz)
#pragma config FPLLMUL = MUL_20 // PLL Multiply (now 80 MHz)
#pragma config FPLLODIV = DIV_2 // Divide After PLL (now 40 MHz)
// see figure 8.1 in datasheet for more info
#pragma config FWDTEN = OFF // Watchdog Timer Disabled
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select
#pragma config JTAGEN = OFF // Disable JTAG
#pragma config FSOSCEN = OFF // Disable Secondary Oscillator
#pragma config FPBDIV = DIV_1 // PBCLK = SYCLK
// Defines
#define SYSCLK 40000000L
// Macros
// Equation to set baud rate from UART reference manual equation 21-1
#define Baud2BRG(desired_baud) ( (SYSCLK / (16*desired_baud))-1)
// Function Prototypes
int SerialTransmit(const char *buffer);
unsigned int SerialReceive(char *buffer); //, unsigned int max_size);
int UART2Configure( int baud);
short a2dvals[11000];
int adcptr,num_channels,k,i;
char sampling;
int ADC_RSLT0,totaldata,totaldata1,chunks_sent,data_count,l;
short temp;
BOOL a2don;
volatile unsigned int channel4;
void __ISR(_ADC_VECTOR, IPL2) TIMER3Handler(void) // Fonction d'interruption Timer 3
{
temp = ReadADC10(0);
a2dvals[k] = (temp);
k++;
if (k>totaldata1)// && sampling == 's')
{
T3CONCLR = 0x8000;
a2don=FALSE;
chunks_sent = 0;
totaldata = k/2;
k = 1;
}
mAD1ClearIntFlag();
}
int main(void)
{
char buf[1024]; // declare receive buffer with max size 1024
// Peripheral Pin Select
U2RXRbits.U2RXR = 4; //SET RX to RB8
RPB9Rbits.RPB9R = 2; //SET RB9 to TX
SYSTEMConfigPerformance(SYSCLK);
UART2Configure(9600); // Configure UART2 for a baud rate of 9600
U2MODESET = 0x8000; // enable UART2
ANSELBbits.ANSB2 = 1; // set RB2 (AN4) to analog
TRISBbits.TRISB2 = 1; // set RB2 as an input
//adcConfigureManual(); // Configure ADC
//AD1CON1SET = 0x8000; // Enable ADC
SerialTransmit("Hello! Enter 'a' to do ADC conversion \r\n");
unsigned int rx_size;
while( 1){
rx_size = SerialReceive(buf); //, 1024); // wait here until data is received
SerialTransmit(buf); // Send out data exactly as received
SerialTransmit("\r\n");
}
return 1;
} // END main()
/* UART2Configure() sets up the UART2 for the most standard and minimal operation
* Enable TX and RX lines, 8 data bits, no parity, 1 stop bit, idle when HIGH
* Input: Desired Baud Rate
* Output: Actual Baud Rate from baud control register U2BRG after assignment*/
int UART2Configure( int desired_baud){
U2MODE = 0; // disable autobaud, TX and RX enabled only, 8N1, idle=HIGH
U2STA = 0x1400; // enable TX and RX
U2BRG = Baud2BRG(desired_baud); // U2BRG = (FPb / (16*baud)) - 1
// Calculate actual assigned baud rate
int actual_baud = SYSCLK / (16 * (U2BRG+1));
return actual_baud;
} // END UART2Configure()
/* SerialTransmit() transmits a string to the UART2 TX pin MSB first
*
* Inputs: *buffer = string to transmit */
int SerialTransmit(const char *buffer)
{
unsigned int size = strlen(buffer);
while( size)
{
while( U2STAbits.UTXBF); // wait while TX buffer full
U2TXREG = *buffer; // send single character to transmit buffer
buffer++; // transmit next character on following loop
size--; // loop until all characters sent (when size = 0)
}
while( !U2STAbits.TRMT); // wait for last transmission to finish
return 0;
}
/* SerialReceive() is a blocking function that waits for data on
* the UART2 RX buffer and then stores all incoming data into *buffer
*
* Note that when a carriage return '\r' is received, a nul character
* is appended signifying the strings end
*
* Inputs: *buffer = Character array/pointer to store received data into
* max_size = number of bytes allocated to this pointer
* Outputs: Number of characters received */
unsigned int SerialReceive(char *buffer) //, unsigned int max_size)
{
//unsigned int num_char = 0;
/* Wait for and store incoming data until either a carriage return is received
* or the number of received characters (num_chars) exceeds max_size */
while(1)
{
while( !U2STAbits.URXDA); // wait until data available in RX buffer
*buffer = U2RXREG; // empty contents of RX buffer into *buffer pointer
if (*buffer == 'a')
{
int dummy,dummy1;
unsigned char tempstr[5];
SYSTEMConfig(SYSCLK, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
// the ADC ///////////////////////////////////////
// configure and enable the ADC
CloseADC10(); // ensure the ADC is off before setting the configuration
// define setup parameters for OpenADC10
// Turn module on | ouput in integer | trigger mode auto | enable autosample
// ADC_CLK_AUTO -- Internal counter ends sampling and starts conversion (Auto convert)
// ADC_AUTO_SAMPLING_ON -- Sampling begins immediately after last conversion completes; SAMP bit is automatically set
// ADC_AUTO_SAMPLING_OFF -- Sampling begins with AcquireADC10();
#define PARAM1 ADC_MODULE_ON|ADC_FORMAT_INTG32 | ADC_CLK_TMR | ADC_AUTO_SAMPLING_ON //
// define setup parameters for OpenADC10
// ADC ref external | disable offset test | disable scan mode | do 1 sample | use single buf | alternate mode off
#define PARAM2 ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF
//
// Define setup parameters for OpenADC10
// use peripherial bus clock | set sample time | set ADC clock divider
// ADC_CONV_CLK_Tcy2 means divide CLK_PB by 2 (max speed)
// ADC_SAMPLE_TIME_5 seems to work with a source resistance < 1kohm
#define PARAM3 ADC_CONV_CLK_SYSTEM | ADC_SAMPLE_TIME_5 | ADC_CONV_CLK_Tcy2 //ADC_SAMPLE_TIME_15| ADC_CONV_CLK_Tcy2
// define setup parameters for OpenADC10
// set AN4 and as analog inputs
#define PARAM4 ENABLE_AN4_ANA
// define setup parameters for OpenADC10
// do not assign channels to scan
#define PARAM5 SKIP_SCAN_ALL
// use ground as neg ref for A | use AN4 for input A
// configure to sample AN4
SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN4 ); // configure to sample AN4
OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using the parameters defined above
ConfigIntADC10(ADC_INT_PRI_2 | ADC_INT_ON);
EnableADC10(); // Enable the ADC
INTEnableSystemMultiVectoredInt();
OpenTimer3(T3_OFF | T3_SOURCE_INT | T3_PS_1_1 ,0x3e8);
num_channels = 1;
totaldata1 = 10500;
a2don=TRUE;
T3CONSET = 0x8000;
k=0;
while(1)
{
while(a2don);
for(i=0;i<100;i++)
{
dummy = a2dvals[i]/1000 ;
tempstr[0] = dummy + 0x30;
dummy1 = a2dvals[i]- dummy*1000;
dummy = dummy1/100;
tempstr[1] = dummy + 0x30;
dummy1 = dummy1 - dummy*100;
dummy = dummy1/10;
tempstr[2] = dummy + 0x30;
dummy1 = dummy1 - dummy*10;
tempstr[3] = dummy1 + 0x30;
//tempstr[4] = "\0";
printf("%c%c%c%c \n", tempstr[0],tempstr[1],tempstr[2],tempstr[3]);
}
a2don=TRUE;
}
}
}
return 1;
}// END SerialReceive()
enter image description here
Thanks for your advices.
You do not need to reset the Pickit. If anything, that might be the least efficient way to do it (arguably).
Rather try something like this. Please note this is high level. You will need to make it work yourself.
void(main){
// Setup your things here
while(1){ // Your infinite loop
// Check if you received 'a' here
if (received_a == 1){ // You received a 'a'
send_data(); // Send your data
}
}
}
Without providing actual code you have written we will not be able to help you.
You use while(1) loops everywhere, and if you don't use a break; or return command you stay in that loop forever.
I think you don't need while(1) loops in the functions except in main(). Remove these and it should work.
Try drawing out your program flow in a flow chart, it should clear things up. Also consider using a state machine using switch/case. It makes it a lot clearer where you are in the code and it's easier to debug. Also, it's probably even better to use interrupts for adc and the serial port. You free up the pic to do other stuff while peripherals are doing stuff that takes time.

FSInit() - "CE_BAD_PARTITION"

I am using a PIC18F26K80 and an XC8 compiler. I am trying to initialise an SD card and create a file. I have simply formatted the SD card on Windows to have a "FAT32" file system and an "Allocation unit size" of 512 bytes. The capacity of the SD card is 2GB. I am using the MDD library from the MLA Legacy version. My main is the following:
FSFILE * file;
char sendBuffer[22] = "This is test string 1";
//**************************************************
// main function
//**************************************************
int main()
{
initIO();
LATBbits.LATB0 = 0;
// Initialise SPI and SD-card
while ( !MDD_MediaDetect() );
// Initialize the device
while ( !FSInit() );
// Initialize
#ifdef ALLOW_WRITES
// Create a new file
file = FSfopenpgm ( "FILE.TXT", "w" );
if ( file == NULL )
while(1);
// Write 21 1-byte objects from sendBuffer into the file
if ( FSfwrite ( (void *) sendBuffer, 1, 21, file ) != 21 )
while(1);
// Close the file
if ( FSfclose ( file ) )
while(1);
#endif
LATBbits.LATB0 = 1; //LED
while(1) {}
return (0);
}
The program gets stuck inside the function "FSInit()" and the error I get from the function is "CE_BAD_PARTITION", which means "The boot record is bad".
The "initIO()" function is the following:
//==============================================================================
// void initIO( void );
//==============================================================================
// Sets the pins on the PIC to input or output and determines the speed of the
// internal oscilaltor
// input: none
// return: none
//==============================================================================
void initIO()
{
OSCCON = 0x75; // Clock speed = 32MHz (4x8Mhz)
TRISA = 0;
TRISB = 0;
TRISC = 0;
TRISBbits.TRISB0 = 0; //LED
TRISCbits.TRISC3 = 0; // set SCL pin as output
TRISCbits.TRISC4 = 1; // set RC4 pin as input
TRISCbits.TRISC5 = 0;
TRISAbits.TRISA5 = 0;
}

Resources