Hello,
I am trying to control a PWM signal that runs at 50Hz, with the aim of using it for automatic testing. A file will be provided on an SD card that shows the duration of the PWM signal in milliseconds, and the duty cycle as a number between 1000 and 2000, representing 1mS and 2mS, for each test.
It seems to work more or less okay apart from when it first starts.
If I have the following instructions in test.txt
40, 1000,
4000, 2000
4000, 1000
I would expect to get two PWM cycles with 1mS signal, followed by four seconds worth of PWM with a duty cycle at 2mS etc. However, whenever the code starts to run I only get one PWM cycle at 1mS as shown below.
I would be extremely grateful if someone could show me the error of my ways.
regards
Bodger
I am trying to control a PWM signal that runs at 50Hz, with the aim of using it for automatic testing. A file will be provided on an SD card that shows the duration of the PWM signal in milliseconds, and the duty cycle as a number between 1000 and 2000, representing 1mS and 2mS, for each test.
It seems to work more or less okay apart from when it first starts.
If I have the following instructions in test.txt
40, 1000,
4000, 2000
4000, 1000
I would expect to get two PWM cycles with 1mS signal, followed by four seconds worth of PWM with a duty cycle at 2mS etc. However, whenever the code starts to run I only get one PWM cycle at 1mS as shown below.
I would be extremely grateful if someone could show me the error of my ways.
regards
Bodger
Code:
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <SD.h>
#include <SPI.h>
#include <PWMServo.h>
PWMServo myservo; // create servo object to control a servo
#define LED LED_BUILTIN /* Set LED pin number */
#define PIN_LOW 0
#define PIN_HIGH 1
#define RESET_COUNT_MS 500U
#define ONE_SECOND 1000
// Create an IntervalTimer object
IntervalTimer myTimer;
// Create an IntervalTimer object
IntervalTimer myTimer_2;
bool f_once;
uint8_t ledState;
uint8_t PWM_time_on;
uint8_t PWM_state;
uint8_t pin_state;
uint32_t waiting;
uint32_t waiting_old;
uint32_t loop_count;
uint32_t debounce_count;
uint64_t SDcard_mem_used;
uint64_t SDcard_total_mem;
uint64_t SDcard_mem_avail;
File myFile;
//---------------------------------------------------------
void Initialise_Variables(void)
{
waiting = 0U;
waiting_old = 0U;
loop_count = 0U;
debounce_count = 0U;
ledState = LOW;
f_once = true;
}
//---------------------------------------------------------
void Write_PWM_Data(int step_time, int PWM_Value)
{
float f_value;
elapsedMillis waiting;
if (PWM_Value <= 1000)
{
f_value = 1; //force the output to be 1mS
}
else
{
PWM_Value = PWM_Value - 1000;
f_value = (float)PWM_Value * 0.18; //Scale the output
}
//#ifdef DEBUG_PRINT
Serial.printf("\r\nT = %d D = %d ", (int)step_time, (int)f_value);
//#endif
myservo.write((int)f_value); // tell servo to go to position in variable 'pos'
while (waiting < (unsigned long)step_time)
{}
}
//----------------------------------------------------------
bool readLine(File &f, char* line, size_t maxLen) {
for (size_t n = 0; n < maxLen; n++) {
int c = f.read();
if ( c < 0 && n == 0) return false; // EOF
if (c < 0 || c == '\n') {
line[n] = 0;
return true;
}
line[n] = c;
}
return false; // line too long
}
//---------------------------------------------------------
void Read_File(void)
{
char line[100];
char *sp;
int step_time;
int PWM_duty_time;
int line_count = 0;
while (myFile.available())
{
if (!readLine(myFile, line, sizeof(line)))
{
Serial.println("EOF or too long"); // EOF or too long
}
else
{
sp = strtok(line, ",");
if (sp != NULL)
{
step_time = atoi(sp);
#ifdef DEBUG_PRINT
Serial.printf("\Time = %d", step_time);
#endif
sp = strtok(NULL, ",");
if (sp != NULL)
{
PWM_duty_time = atoi(sp);
#ifdef DEBUG_PRINT
Serial.printf(" PWM_duty_time = %d", PWM_duty_time);
#endif
Write_PWM_Data(step_time, PWM_duty_time);
}
else
{
#ifdef DEBUG_PRINT
Serial.printf("\r\nfo");
#endif
}
line_count++;
}
else
{
Serial.printf("something wrong! \n");
}
#ifdef DEBUG_PRINT
Serial.printf("\nline count %d", line_count);
#endif
}
}
myFile.close();
}
//----------------------------------------------------------
void blinkLED()
{
if (ledState == LOW)
{
ledState = HIGH;
} else
{
ledState = LOW;
}
digitalWrite(LED, ledState);
}
//---------------------------------------------------------
void Check_for_Reset(uint32_t time_ms)
{
pin_state = digitalRead(PIN_A2);
if (pin_state == PIN_LOW)
{
if (debounce_count == RESET_COUNT_MS)
{
#ifdef DEBUG_PRINT
Serial.println("Reset count reached \r\n");
#endif
}
else
{
debounce_count++;
}
}
else
{
if (debounce_count == RESET_COUNT_MS)
{
if (pin_state == PIN_HIGH) //Wait for pin release
{
Serial.println("Reset here");
delay(ONE_SECOND);
SRC_GPR5 = 0x0BAD00F1;
SCB_AIRCR = 0x05FA0004;
}
}
else
{
debounce_count = 0U;
}
}
}
//---------------------------------------------------------
void Wait_for_Start(void)
{
myTimer.begin(blinkLED, 250000); // blinkLED to run every 0.15 seconds
while (true)
{
pin_state = digitalRead(PIN_A2);
//Check the initial state
if (pin_state == PIN_HIGH)
{
if (f_once)
{
f_once = false;
Serial.printf("\r\npin state currently HIGH \r\n");
}
}
else
{
Serial.printf("\r\npin state currently LOW \r\n");
break;
}
}
myTimer.end();
digitalWrite(LED, LOW);
}
//---------------------------------------------------------
void setup()
{
elapsedMillis waiting;
Serial.begin(115200);
delay(400);
// put your setup code here, to run once:
Serial.println("\r\nVersion Number V_1.0.0.A \r\n");
pinMode ( LED, OUTPUT ); /* Setup the LED */
pinMode (3, OUTPUT);
pinMode (PIN_A2, INPUT_PULLUP);
if (!SD.begin(BUILTIN_SDCARD))
{
Serial.println(("SD initialization failed!"));
myTimer_2.begin(blinkLED, 2000000); // blinkLED to run every 0.15 seconds
while (1)
{loop_count++;}
}
else
{
Serial.println(("SD initialization complete. \r\n"));
// open the file.
myFile = SD.open("test.txt", FILE_READ);
if (myFile)
{
Serial.println("File (test.csv) found");
SDcard_total_mem = SD.totalSize();
SDcard_mem_used = SD.usedSize();
SDcard_mem_avail = SDcard_total_mem - SDcard_mem_used;
Serial.printf("\r\n Total mem %llu Used mem %llu \r\n", SDcard_total_mem, SDcard_mem_used);
Serial.printf("\r\n Total mem avail %llu 0x%llx \r\n", SDcard_mem_avail, SDcard_mem_avail);
}
else
{
Serial.println("File (test.csv) not found");
myTimer_2.begin(blinkLED, 3000000); // blinkLED to run every 3 seconds
while (true)
{loop_count++;} //give the processor something to do
}
}
Initialise_Variables();
Wait_for_Start();
myservo.attach(SERVO_PIN_A, 1000, 2000); // some motors need min/max setting
delay(500); //let the servo settle
Read_File(); //read the file and set servo accordingly
}
//---------------------------------------------------------
void loop()
{
waiting = millis();
if (waiting != waiting_old)
{
loop_count++;
waiting_old = waiting;
Check_for_Reset(waiting);
}
if (loop_count == ONE_SECOND)
{
loop_count = 0U;
digitalToggle(LED);
}
}