Time errors in ADC - signal-processing

I measure distance using ultrasonic signal. STM32F1 generate Ultrasound signal, STM32F4 writing this signal using microphone. Both STM32 are synchronized using signal generated another device, they connected one wire.
Question: Why signal comes with different times? although I don’t move receiver or transmitter. It's gives errors 50mm.
Dispersion signals
Code of receiver is here:
while (1)
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) != 0x00)
{
Get_UZ_Signal(uz_signal);
Send_Signal(uz_signal);
}
}
void Get_UZ_Signal(uint16_t* uz_signal)
{
int i,j;
uint16_t uz_buf[10];
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uz_buf, 300000);
for(i = 0; i<lenght_signal; i++)
{
j=10;
while(j>0)
{
j--;
}
uz_signal[i] = uz_buf[0];
}
HAL_ADC_Stop_DMA(&hadc1);
}
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
More information here:
https://github.com/BooSooV/Indoor-Ultrasonic-Positioning-System/tree/master/Studying_ultrasonic_signals/Measured_lengths_dispersion
PROBLEM RESOLVED
Dispersion signals final
The time errors was created by the transmitter, I make some changed in it. Now synchro signal takes with help EXTI, and PWM generated all time, and I controlee signal with Enable or Disable pin on driver. Now I have dispersion 5mm, it enough for me.
Final programs is here
https://github.com/BooSooV/Indoor-Ultrasonic-Positioning-System/tree/master/Studying_ultrasonic_signals/Measured_lengths_dispersion

Maybe, It is a problem of time processing. The speed of sound is 343 meters / sec. Then, 50mm is about 0.15 msec.
Have you thought to call HAL_ADC_Start_DMA() from the main()
uint16_t uz_buf[10];
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uz_buf, 10 );//300000);
// Sizeof Buffer ---------------------^
and you call
void Get_UZ_Signal(uint16_t* uz_signal) {
int i;
// For debugging - Get the time to process
// Get the Time from the System Tick. This counter wrap around
// from 0 to SysTick->LOAD every 1 msec
int32_t startTime = SysTick->VAL;
__HAL_ADC_ENABLE(&hadc1); // Start the DMA
// return remaining data units in the current DMA Channel transfer
while(__HAL_DMA_GET_COUNTER(&hadc1) != 0)
;
for(i = 0; i<lenght_signal; i++) {
// uz_signal[i] = uz_buf[0];
// 0 or i ------------^
uz_signal[i] = uz_buf[i];
__HAL_ADC_DISABLE(&hadc1); // Stop the DMA
int32_t endTime = SysTick->VAL;
// check if negative, case of wrap around
int32_t difTime = endTime - startTime;
if ( difTime < 0 )
difTime += SysTick->LOAD
__HAL_DMA_SET_COUNTER(&hadc1, 10); // Reset the counter
// If the DMA buffer is 10, the COUNTER will start at 10
// and decrement
// Ref. Manual: 9.4.4 DMA channel x number of data register (DMA_CNDTRx)

In your code
MX_USART1_UART_Init();
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uz_signal, 30000);
// Must be stopped because is running now
// How long is the buffer: uint16_t uz_signal[ 30000 ] ?
__HAL_ADC_DISABLE(&hadc1); // must be disable
// reset the counter
__HAL_DMA_SET_COUNTER(&hdma_adc1, 30000);
while (1)
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) != 0x00)
{
__HAL_ADC_ENABLE(&hadc1);
while(__HAL_DMA_GET_COUNTER(&hdma_adc1) != 0)
;
__HAL_ADC_DISABLE(&hadc1);
__HAL_DMA_SET_COUNTER(&hdma_adc1, 30000);
// 30,000 is the sizeof your buffer?
...
}
}

I made some test with uC STM32F407 # 168mHz. I'll show you the code below.
The speed of sound is 343 meters / second.
During the test, I calculated the time to process the ADC conversion. Each conversion takes about 0.35 uSec (60 ticks).
Result
Size Corresponding
Array Time Distance
100 0.041ms 14mm
1600 0.571ms 196mm
10000 3.57ms 1225mm
In the code, you'll see the start time. Be careful, the SysTick is a decremental counter starting # the uC speed (168MHz = from 168000 to 0). It could be good idea to get the msec time with HAL_GetTick(), and usec with SysTick.
int main(void)
{
...
MX_DMA_Init();
MX_ADC1_Init();
// Configure the channel in the way you want
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_0; //ADC1_CHANNEL;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// Start the DMA channel and Stop it
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uz_signal, sizeof( uz_signal ) / sizeof( uint16_t ));
HAL_ADC_Stop_DMA( &hadc1 );
// The SysTick is a decrement counter
// Can be use to count usec
// https://www.sciencedirect.com/topics/engineering/systick-timer
tickLoad = SysTick->LOAD;
while (1)
{
// Set the buffer to zero
for( uint32_t i=0; i < (sizeof( uz_signal ) / sizeof( uint16_t )); i++)
uz_signal[i] = 0;
// Reset the counter ready to restart
DMA2_Stream0->NDTR = (uint16_t)(sizeof( uz_signal ) / sizeof( uint16_t ));
/* Enable the Peripheral */
ADC1->CR2 |= ADC_CR2_ADON;
/* Start conversion if ADC is effectively enabled */
/* Clear regular group conversion flag and overrun flag */
ADC1->SR = ~(ADC_FLAG_EOC | ADC_FLAG_OVR);
/* Enable ADC overrun interrupt */
ADC1->CR1 |= (ADC_IT_OVR);
/* Enable ADC DMA mode */
ADC1->CR2 |= ADC_CR2_DMA;
/* Start the DMA channel */
/* Enable Common interrupts*/
DMA2_Stream0->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT;
DMA2_Stream0->FCR |= DMA_IT_FE;
DMA2_Stream0->CR |= DMA_SxCR_EN;
//===================================================
// The DMA is ready to start
// Your if(HAL_GPIO_ReadPin( ... ) will be here
HAL_Delay( 10 );
//===================================================
// Get the time
tickStart = SysTick->VAL;
// Start the DMA
ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART;
// Wait until the conversion is completed
while( DMA2_Stream0->NDTR != 0)
;
// Get end time
tickEnd = SysTick->VAL;
/* Stop potential conversion on going, on regular and injected groups */
ADC1->CR2 &= ~ADC_CR2_ADON;
/* Disable the selected ADC DMA mode */
ADC1->CR2 &= ~ADC_CR2_DMA;
/* Disable ADC overrun interrupt */
ADC1->CR1 &= ~(ADC_IT_OVR);
// Get processing time
tickDiff = tickStart - tickEnd;
//===================================================
// Your processing will go here
HAL_Delay( 10 );
//===================================================
}
}
So, you'll have the start and end time. I think you have to make the formula on the start time.
Good luck

If you want to know the execution time, you could use that little function. It returns the micro Seconds
static uint32_t timeMicroSecDivider = 0;
extern uint32_t uwTick;
// The SysTick->LOAD matchs the uC Speed / 1000.
// If the uC clock is 80MHz, the the LOAD is 80000
// The SysTick->VAL is a decrement counter from (LOAD-1) to 0
//====================================================
uint64_t getTimeMicroSec()
{
if ( timeMicroSecDivider == 0)
{
// Number of clock by micro second
timeMicroSecDivider = SysTick->LOAD / 1000;
}
return( (uwTick * 1000) + ((SysTick->LOAD - SysTick->VAL) / timeMicroSecDivider));
}

Related

writing all 1s or 0s to 23k640 SRAM

Hi please find my code below, I am trying to write to SRAM. please help
my code below reads the output from a cell but i can't write to that cell
CS: pin 12
MOSI: pin 8
MISO: pin 10
SCK: pin 9
*/
#include <SPI.h>
//SRAM opcodes
#define RDSRAM 5 //00000101
#define WRSRAM 1 //00000001
#define READ 3 //00000011
#define WRITE 2 //00000010
int *ptr;
int CS = 12;
int CSS = 8;
char buf [90];
int response_pair;
int entryval;
int codeAddr = 545;
char s [90];
//char value = *(char*)0x5C;
uint8_t Spi23K640Rd8(uint32_t address){
uint8_t read_byte;
digitalWrite(CS,LOW);
SPI.transfer(READ);
//SPI.transfer((uint8_t)(address >> 16) & 0xff);
SPI.transfer((uint8_t)(address >> 8) & 0xff);
SPI.transfer((uint8_t)address);
read_byte = SPI.transfer(0x00);
digitalWrite(CS,HIGH);
return read_byte;
}
void Spi23K640Wr8(uint32_t address, uint8_t data_byte)
{
SPI.transfer(WRITE);
SPI.transfer((uint8_t)(address >> 16) & 0xff);
SPI.transfer((uint8_t)(address >> 8) & 0xff);
SPI.transfer((uint8_t)address);
SPI.transfer(data_byte);
}
void setup(void) {
// char *ptr;
// char myvar[1] = {545};
uint64_t i;
uint8_t value;
ptr=&codeAddr;
/* all pins on the Port B set to output-low */
pinMode(CSS, OUTPUT);
digitalWrite(CSS, HIGH);
pinMode(CS, OUTPUT);
Serial.begin(9600);
delay(2500);
SPI.begin();
for (i=0; i<=8192; i++) { // Do all memory locations, 64 Kbit SRAM = 65536 / 8 = 8192
Spi23K640Wr8(i, (uint8_t)i);
value = Spi23K640Rd8(i);
Serial.print((uint64_t)value, DEC);
if ( !(i % 32) && !(i==0) ) { // Every 32, do a new line and don't do the first item either
Serial.println(value);
} else
{ // Other wise, print a comma
Serial.print(",");
}
}
while (!Serial) ;
int response_pair = Spi23K640Rd8 (codeAddr);
Serial.println ("Enter Challenge");
//Spi23K640Wr8();
delay(500);
}
void loop() {
//while (!Serial) ;
int response_pair = Spi23K640Rd8 (codeAddr);
if (Serial.available ()) {
int n = Serial.readBytesUntil ('\n', buf, sizeof (buf)-1); //.toInt(); //save read value method to n
buf [n] = '\0';
sscanf (buf, "%o", &entryval); //check values
sprintf (s, " buf %s, response_pair %o entryval %o", buf, response_pair, entryval); //point the values from the pointer
if(entryval == response_pair )
{
Serial.println ("RESPONSE PAIR MATCHES ");
Serial.println ("loading address......");
Serial.print ("CRP address output = ");
Serial.println (Spi23K640Rd8(codeAddr), DEC); //prints out specific address
Serial.println ("Authenticate Chip");
Serial.println (s);
//delay (500);
}
else if (response_pair != entryval)
{
Serial.println ("INTRUDER ALERT!!!Wrong challenge");
Serial.println (s); //print the values in different types
delay (n);
}
// return;
// while (!Serial) ;
Serial.println();
Serial.println ("Enter Another Challenge"); //start the process again
//Serial.println (s); //print the values in different types
}
// put your main code here, to run repeatedly:
//Serial.println("Hello LoRa");
//delay(50);
//ptr++;
}
i was able to read the power up state but haven't had any luck writing to the SRAM cells
any suggestions will be appreciated. i am on a tight schedule.
disregard beloww
We have established that In order to evaluate the properties of the SRAM as a PUF, we perform a number of specifically selected tests to investigate the behaviour of the start-up values of the SRAM memory
• The technique can be viewed as an attempt to read multiple cells in a column at the same time, creating contention that is resolved according to process variation
• An authentication challenge is issued to the array of SRAM cells by activating two or more wordlines concurrently
• The response is simply the value that the SRAM produces from a read operation when the challenge condition is applied
• The number of challenges that can be applied the array of SRAM cells grows exponentially with the number of SRAM rows and these challenges can be applied at any time without power cycling
• providing an array of different responses on different chips ; these challenges are SRAM cells arranged in rows and columns where SRAM cells in each column and array share a worldlines
• SRAM cells in each column in the array share common is a graph illustrating the number of unbiased bit lines
The CS line is not asserted during the write operation, and the SRAM uses 16 and not 24-bit addresses. You can try changing your read and write functions to something like this:
uint8_t Spi23K640Rd8(uint16_t address) { // <-- change from uint32_t to uint16_t
uint8_t read_byte;
digitalWrite(CS, LOW); // That's good
SPI.transfer(READ); // Read # 16-bit address, that's good
SPI.transfer((uint8_t)(address >> 8) & 0xff);
SPI.transfer((uint8_t)address);
read_byte = SPI.transfer(0x00);
digitalWrite(CS, HIGH);
return read_byte;
}
void Spi23K640Wr8(uint16_t address, uint8_t data_byte) { // <-- change from uint32_t to uint16_t
digitalWrite(CS, LOW); // Was missing.
SPI.transfer(WRITE); // write #16-bit address
// SPI.transfer((uint8_t)(address >> 16) & 0xff); // <- BUG!!! this byte is not expected!
SPI.transfer((uint8_t)(address >> 8) & 0xff);
SPI.transfer((uint8_t)address);
SPI.transfer(data_byte);
digitalWrite(CS, HIGH); // clear CS.
}
Note: You should also consider renaming these functions to make your code easier to read.
How about replacing
uint8_t Spi23K640Rd8(uint16_t address);
void Spi23K640Wr8(uint16_t address, uint8_t data_byte);
With
uint8_t SRAM_23K640_ReadByte(uint16_t address);
void SRAM_23K640_WriteByte(uint16_t address, uint8_t data_byte);
Or whatever you see fit. Keep in mind that our eyes and brain have a much easier time reading shorter, pronounceable words. When the brain is too busy reading long mumbo jumbo, thinking about other things, like what the code does, becomes more difficult.

Sleep delta to check cycles count

// Pseudocode
void sleep::check_delta()
{
const auto tick_count = GetTickCount
Sleep(1000)
const auto tick_delta = GetTickCount() - tick_count
if (tick_delta >= 1200)
{
sleep_report.unknown = 0
sleep_report.report_id = 0x45
sleep_report.delta = tick_delta
battleye::report(&sleep_report, sizeof(sleep_report), 0
}
}
In one of the articles about reverse-engineering BattlEye anticheat, it is said that anticheat sends the process to sleep, and checks the number of cycles before and after inactivity. How to explain these actions?

Problem reading data from multiple ADC channels with stm32f4-discovery board using DMA

I am trying to read data from channel 0,1,2 and 3 of ADC1. The issue is that when I read from channel 1 and channel 2 and run the code in debug mode it shows the correct valueenter image description heres but when I modified it for doing the same for channel 3 and 4 also,it does not show any value.Following is the code and the screen shot of memory map:
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
uint16_t ADC1ConvertedValue[4] = {0,0,0,0};//Stores converted vals [2] = {0,0}
void DMA_config()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 ,ENABLE);
DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.DMA_Channel = DMA_Channel_0;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t) 0x4001204C;//ADC1's data register
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.DMA_BufferSize = 4;//2
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//Reads 16 bit values _HalfWord
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//Stores 16 bit values _Halfword
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;//_HalfFull
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStruct);
DMA_Cmd(DMA2_Stream0, ENABLE);
}
void ADC_config()
{
/* Configure GPIO pins ******************************************************/
ADC_InitTypeDef ADC_InitStruct;
ADC_CommonInitTypeDef ADC_CommonInitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//ADC1 is connected to the APB2 peripheral bus
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;// PA0,PA1,PA3,PA3
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;//The pins are configured in analog mode
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;//We don't need any pull up or pull down
GPIO_Init(GPIOA, &GPIO_InitStruct);//Initialize GPIOA pins with the configuration
/* ADC Common Init **********************************************************/
ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStruct);
/* ADC1 Init ****************************************************************/
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit int (max 4095)
ADC_InitStruct.ADC_ScanConvMode = ENABLE;//The scan is configured in multiple channels
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//Continuous conversion: input signal is sampled more than once
ADC_InitStruct.ADC_ExternalTrigConv = DISABLE;
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//Data converted will be shifted to right
ADC_InitStruct.ADC_NbrOfConversion = 4;
ADC_Init(ADC1, &ADC_InitStruct);//Initialize ADC with the configuration
/* Select the channels to be read from **************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_144Cycles);//PA0
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_144Cycles);//PA1
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_144Cycles);//PA2
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_144Cycles);//PA3
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
}
int main(void)
{
DMA_config();
ADC_config();
while(1)
{
ADC_SoftwareStartConv(ADC1);
//value=ADC_Read();
}
return 0;
}
You shouldn't start the ADC conversion multiple times (in your while(1) loop).
Since you've configured the ADC with .ADC_ContinuousConvMode = ENABLE it should be enough to start it before the loop and do nothing within it.

Why [ MetaTrader 4 ] can't write/open a file in windows 10 with the FileWrite() function?

I tried implementing the solutions from this post
Cannot open file on Ubuntu
But to no avail. I keep getting a 5002 error. (failed to open file) after FileWrite()
Even when I try out the example script on https://docs.mql4.com/files/filewrite
I get the same error. I tried running MetaTrader Terminal 4 in administrator mode but to no avail either.Does anyone know a solution to this?
#property version "1.00"
#property strict
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
input string InpSymbolName = "EURUSD"; // Сurrency pair
input ENUM_TIMEFRAMES InpSymbolPeriod = PERIOD_H1; // Time frame
input int InpFastEMAPeriod = 12; // Fast EMA period
input int InpSlowEMAPeriod = 26; // Slow EMA period
input int InpSignalPeriod = 9; // Difference averaging period
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE; // Price type
//--- parameters for writing data to file
input string InpFileName = "MACD.csv"; // File name
input string InpDirectoryName = "Data"; // Folder name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
bool sign_buff[]; // signal array (true - buy, false - sell)
datetime time_buff[]; // array of signals' appear time
int sign_size=0; // signal array size
double macd_buff[]; // array of indicator values
datetime date_buff[]; // array of indicator dates
int macd_size=0; // size of indicator arrays
//--- set indexing as time series
ArraySetAsSeries( sign_buff, true );
ArraySetAsSeries( time_buff, true );
ArraySetAsSeries( macd_buff, true );
ArraySetAsSeries( date_buff, true );
//--- reset last error code
ResetLastError();
//--- copying the time from last 1000 bars
int copied = CopyTime( NULL, 0, 0, 1000, date_buff );
if ( copied <= 0 )
{ PrintFormat( "Failed to copy time values. Error code = %d", GetLastError() );`
return;
}
//--- prepare macd_buff array
ArrayResize( macd_buff, copied );
//--- copy the values of main line of the iMACD indicator
for ( int i = 0; i< copied; i++ )
{ macd_buff[i] = iMACD( InpSymbolName, InpSymbolPeriod, InpFastEMAPeriod, InpSlowEMAPeriod, InpSignalPeriod, InpAppliedPrice, MODE_MAIN, i );
}
//--- get size
macd_size = ArraySize( macd_buff );
//--- analyze the data and save the indicator signals to the arrays
ArrayResize( sign_buff, macd_size - 1 );
ArrayResize( time_buff, macd_size - 1 );
for ( int i = 1; i < macd_size; i++ )
{
//--- buy signal
if ( macd_buff[i-1] < 0
&& macd_buff[i] >= 0 )
{
sign_buff[sign_size] = true;
time_buff[sign_size] = date_buff[i];
sign_size++;
}
//--- sell signal
if ( macd_buff[i-1] > 0
&& macd_buff[i] <= 0 )
{
sign_buff[sign_size] = false;
time_buff[sign_size] = date_buff[i];
sign_size++;
}
}
//--- open the file for writing the indicator values (if the file is absent, it will be created automatically)
ResetLastError();
int file_handle = FileOpen( InpDirectoryName // aDirNAME
+ "//" // aFileSystemTreeBranchSEPARATOR
+ InpFileName, // aFileNAME
FILE_READ|FILE_WRITE|FILE_CSV // fileIoMODE_FLAGs
);
if ( file_handle != INVALID_HANDLE )
{
PrintFormat( "%s file is available for writing", InpFileName );
PrintFormat( "File path: %s\\Files\\", TerminalInfoString( TERMINAL_DATA_PATH ) );
//--- first, write the number of signals
FileWrite( file_handle, sign_size );
//--- write the time and values of signals to the file
for ( int i = 0; i < sign_size; i++ )
FileWrite( file_handle, time_buff[i], sign_buff[i] );
//--- close the file
FileClose( file_handle );
PrintFormat( "Data is written, %s file is closed", InpFileName );
}
else
PrintFormat( "Failed to open %s file, Error code = %d", InpFileName, GetLastError() );
}
Alt. A)
the algo does not check for a positive presence of an InpDirectoryName node in the filesystem.
Alt. B)
in case the Alt. A) passes, there ought be used a compatible delimiter in aFilePATH + aFileNAME string, i.e. == "\\", ( aFileSystemTreeBranchSEPARATOR ref.: Help for details )
thena fileIO shall take place in \Terminal\Common\Files ( in case a FILE_COMMON bitmask flag was added (used) in the int open_flags parameter),
otherwise,the operations will take place in a (sub)-directory of a MetaTrader Terminal 4 local folder== MQL4\Files ( for a live ExpertAdvisor or Custom Indicator or Script mode of operations )or== MQL4\Tester\Files ( in case of using ExpertAdvisor or Custom Indicatorinside a back-testing framework of MT4 Strategy Tester).

Can't save to Flash Memory?

I am using the following library <flash.h> to Erase/Write/Read from memory but unfortunately the data I am trying to save doesn't seem to be written to flash memory. I am using PIC18F87j11 with MPLAB XC8 compiler. Also when I read the program memory from PIC after attempting to write to it, there is no data on address 0x1C0CA. What am I doing wrong?
char read[1];
/* set FOSC clock to 8MHZ */
OSCCON = 0b01110000;
/* turn off 4x PLL */
OSCTUNE = 0x00;
TRISDbits.TRISD6 = 0; // set as ouput
TRISDbits.TRISD7 = 0; // set as ouput
LATDbits.LATD6 = 0; // LED 1 OFF
LATDbits.LATD7 = 1; // LED 2 ON
EraseFlash(0x1C0CA, 0x1C0CA);
WriteBytesFlash(0x1C0CA, 1, 0x01);
ReadFlash(0x1C0CA, 1, read[0]);
if (read[0] == 0x01)
LATDbits.LATD6 = 1; // LED 1 ON
while (1) {
}
I don't know what WriteFlashBytes does but the page size for your device is 64 bytes and after writing you need to write an ulock sequence to EECON2 and EECON1 registers to start programming the flash memory

Resources