This is the sketch (see the "static void refreshDisplay()") that has worked for many day until yesterday night:
/***************************************************/
/* INCLUDE LIBRARIES */
/***************************************************/
#include "Arduino_GigaDisplay_GFX.h"
#include <mbed.h>
#include <digitalWriteFast.h>
#include <Arduino_AdvancedAnalog.h>
#include <Wire.h>
//#include "LedControl.h"
/***************************************************/
/* DEFINE CONSTANT */
/***************************************************/
#define encA 28 // Encoder A
#define encB 29 // Encoder B
#define potA 39 // Encoder pot A
#define potB 41 // Encoder pot B
#define speedSel0 22 // TX used as Output pin
#define speedSel1 24 // RX used as Output pin
#define speedSel2 26 // RX used as Output pin
#define buttonSet 30 // Button Set (red)
#define buttonFun 31 // Button Function (green)
#define buttonHome 32 // Button Home (black)
#define buttonOpt 33 // Button Optional (blue)
#define pwmGatePin 23 // Enable train of PWM pulses
#define pwmInPin 25 // Read PWM and count pulses
#define watchdog 27 // blink forever until system crshes
#define ledAxisPlus 34 // Led axis +
#define ledAxisMinus 35 // Led axis -
#define ledZero 36 // Led zero
#define ledHome 37 // Led home
#define ledGate 38 // Led Gate (run)
#define gateOn 43 // Check if gate is on
#define pwmPin 40 // PWM out
#define din 2 // Max7219 Data In
#define clk 5 // Max7219 Clock
#define cs 4 // Max7219 Chip Select
#define nDis 2 // Number of MAX7219
#define cyan 0x07FF
#define red 0xf800
#define blue 0x001F
#define green 0x07E0
#define magenta 0xF81F
#define white 0xffff
#define black 0x0000
#define yellow 0xFFE0
/***************************************************/
/* CREATE OBJECTS */
/***************************************************/
GigaDisplay_GFX display;
AdvancedADC adc(A0, A1, A2); // A0 = Pot, A1 = Ground, A2 = 3.3V
PinName pwmOut = digitalPinToPinName(D40);
mbed::PwmOut* pwm = new mbed::PwmOut(pwmOut);
//LedControl lc0=LedControl(din, clk, cs, nDis);
/***************************************************/
/* VARIABLES DECLARATION */
/***************************************************/
volatile long encoderPulses = 0;
volatile long pwmInPulses = 0;
volatile int speedSel;
volatile int curEncA;
volatile int oldEncA;
volatile bool encDir;
volatile int curPotA;
volatile int oldPotA;
unsigned long wdCnt = 0;
bool toggleWD = false;
float pwmFrequency = 100000; // Hz = Hertz
float pwmFrequencyTarget = 100000;
float pwmFrequencyRamp = 1.0;
float feedSpeed;
float feedRange = 0;
volatile float potPerc = 0;
float oldPotPerc = 0;
float minPot = 0;
float maxPot = 0;
float kmV = 0;
int oldSpeedSel = -1;
/***************************************************/
/* SETUP */
/***************************************************/
void setup() {
// Wire.begin();
Serial.begin(115200);
if (!adc.begin(AN_RESOLUTION_16, 16000, 8, 32)) {
Serial.println("Failed to start analog acquisition!");
while (1);
}
attachInterrupt(digitalPinToInterrupt(encA), readEncoder, CHANGE);
pinMode(encA, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(encB), readEncoder, CHANGE);
pinMode(encB, INPUT_PULLUP);
delay(100);
attachInterrupt(digitalPinToInterrupt(potA), readSpeedSelector, CHANGE);
pinMode(potA, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(potB), readSpeedSelector, CHANGE);
pinMode(potB, INPUT_PULLUP);
delay(100);
attachInterrupt(digitalPinToInterrupt(pwmInPin), pwmCount, RISING);
pinMode(pwmInPin, INPUT_PULLUP);
delay(100);
oldEncA = digitalRead(encA);
oldPotA = digitalRead(potA);
pinMode(ledAxisPlus, OUTPUT);
pinMode(ledAxisMinus, OUTPUT);
pinMode(speedSel0, OUTPUT);
pinMode(speedSel1, OUTPUT);
pinMode(speedSel2, OUTPUT);
pinMode(buttonSet, INPUT);
pinMode(buttonFun, INPUT);
pinMode(buttonHome, INPUT);
pinMode(buttonOpt, INPUT);
pinMode(pwmGatePin, OUTPUT);
pinMode(ledGate, OUTPUT);
pinMode(gateOn, INPUT);
pinMode(watchdog, OUTPUT);
digitalWrite(speedSel0, 1);
digitalWrite(speedSel1, 1);
digitalWrite(speedSel2, 1);
digitalWriteFast(pwmGatePin, LOW);
digitalWriteFast(ledGate, HIGH);
encoderPulses = 0;
pwmInPulses = 0;
wdCnt = 0;
speedSel = 0;
feedSpeed = pwmFrequencyTarget * 0.0048828125;
oldPotA = HIGH;
display.begin();
display.setRotation(1);
display.fillScreen(black);
generatePwm();
}
/***************************************************/
/* ISR - Interrupt Service Rputine to count pulses */
/***************************************************/
void pwmCount() {
//if (abs(encoderPulses - pwmInPulses) >= 1) {
if (encoderPulses != pwmInPulses) {
digitalWriteFast(ledAxisPlus, HIGH);
digitalWriteFast(ledAxisMinus, HIGH);
digitalWriteFast(pwmGatePin, HIGH);
digitalWriteFast(ledGate, LOW);
if ((encoderPulses - pwmInPulses) >= 1) {
pwmInPulses++;
digitalWriteFast(ledAxisPlus, LOW);
digitalWriteFast(ledAxisMinus, HIGH);
} else if ((encoderPulses - pwmInPulses) <= -1) {
pwmInPulses--;
digitalWriteFast(ledAxisPlus, HIGH);
digitalWriteFast(ledAxisMinus, LOW);
}
/*
if (encoderPulses > pwmInPulses) {
pwmInPulses++;
}
if (encoderPulses < pwmInPulses) {
pwmInPulses--;
}
*/
if ((pwmInPulses == encoderPulses) && digitalReadFast(gateOn)) {
digitalWriteFast(pwmGatePin, LOW);
digitalWriteFast(ledGate, HIGH);
}
}
}
/***************************************************/
/* 1 Hz Watchdog */
/***************************************************/
void watchdogRun() {
if ((millis() - wdCnt) >= 500) {
toggleWD = !toggleWD;
if (toggleWD) {
digitalWrite(watchdog, HIGH);
} else {
digitalWrite(watchdog, LOW);
}
wdCnt = millis();
}
}
/***************************************************/
/* Read encoder feed speed range selection */
/***************************************************/
void readSpeedSelector() {
curPotA = digitalReadFast(potA);
if (curPotA != oldPotA && curPotA == 1){
if (digitalReadFast(potB) != curPotA) {
if (speedSel > 0) {
speedSel -= 1;
}
} else {
if (speedSel < 7) {
speedSel += 1;
}
}
}
oldPotA = curPotA;
}
/***************************************************/
/* Read encoder feed speed */
/***************************************************/
void readEncoder() {
curEncA = digitalReadFast(encA);
if (curEncA != oldEncA && curEncA == 1){
if (digitalReadFast(encB) != curEncA) {
encoderPulses += 16;
encDir = false;
} else {
encoderPulses -= 16;
encDir = true;
}
}
oldEncA = curEncA;
}
/***************************************************/
/* Generate the PWM signal */
/***************************************************/
void generatePwm() {
pwm->period_us(1000000 / pwmFrequency); // Period = 1000000 microseconds / frequency
pwm->pulsewidth_us(500000 / pwmFrequency); // Duty cycle 50%
}
/***************************************************/
/* Select the speed range */
/***************************************************/
void setSpeedSelection() {
if ((speedSel != oldSpeedSel) || (abs(potPerc - oldPotPerc)) > 0.1) {
pwmFrequencyTarget = 1 + (potPerc * 999.99);
switch (speedSel) {
case 0:
digitalWrite(speedSel0, 1); digitalWrite(speedSel1, 1); digitalWrite(speedSel2, 1);
feedSpeed = pwmFrequencyTarget * 4.8828125; // = pwmFreqTarget / 4000 rpm * 5000 micron per revolution * 1000 * 0.00125 / 256
feedRange = 0;
break;
case 1:
digitalWrite(speedSel0, 0); digitalWrite(speedSel1, 1); digitalWrite(speedSel2, 1);
feedSpeed = pwmFrequencyTarget * 9.765625; // ... / 128
feedRange = 1;
break;
case 2:
digitalWrite(speedSel0, 1); digitalWrite(speedSel1, 0); digitalWrite(speedSel2, 1);
feedSpeed = pwmFrequencyTarget * 19.53125; // ... / 64
feedRange = 2;
break;
case 3:
digitalWrite(speedSel0, 0); digitalWrite(speedSel1, 0); digitalWrite(speedSel2, 1);
feedSpeed = pwmFrequencyTarget * 39.0625; // ... / 32
feedRange = 3;
break;
case 4:
digitalWrite(speedSel0, 1); digitalWrite(speedSel1, 1); digitalWrite(speedSel2, 0);
feedSpeed = pwmFrequencyTarget * 78.125; // ... / 16
feedRange = 4;
break;
case 5:
digitalWrite(speedSel0, 0); digitalWrite(speedSel1, 1); digitalWrite(speedSel2, 0);
feedSpeed = pwmFrequencyTarget * 156.25; // ... / 8
feedRange = 5;
break;
case 6:
digitalWrite(speedSel0, 1); digitalWrite(speedSel1, 0); digitalWrite(speedSel2, 0);
feedSpeed = pwmFrequencyTarget * 312.5; // ... / 4
feedRange = 6;
break;
case 7:
digitalWrite(speedSel0, 0); digitalWrite(speedSel1, 0); digitalWrite(speedSel2, 0);
feedSpeed = pwmFrequencyTarget * 625; // ... / 2
feedRange = 7;
break;
}
feedSpeed = (long)(feedSpeed * 0.00125);
feedSpeed = feedSpeed/1000.0;
pwmFrequency = round(pwmFrequencyTarget);
oldPotPerc = potPerc;
oldSpeedSel = speedSel;
}
if (pwmFrequencyRamp < 1.0) {
pwmFrequencyRamp += 0.01;
}
pwmFrequency = pwmFrequency * pwmFrequencyRamp;
}
/***************************************************/
/* Read the digital inputs */
/***************************************************/
void readInputs() {
if (digitalRead(buttonSet) == LOW) {
pwmFrequencyRamp = 0.2;
encoderPulses = 100000; // Every 4000 pulses = 5 mm or 5000 microns
}
if ((digitalRead(buttonOpt) == LOW) && (digitalRead(buttonHome) == HIGH)) { // Go to Zero position
encoderPulses = 0;
}
if ((digitalRead(buttonOpt) == LOW) && (digitalRead(buttonHome) == LOW)) { // Set this position as Zero
encoderPulses = 0;
pwmInPulses = 0;
pwmFrequencyRamp = 0.2;
}
}
/***************************************************/
/* Read the speed potentiometer */
/***************************************************/
void readPot() {
if (adc.available()) {
SampleBuffer buf = adc.read();
potPerc = (buf[0] * 0.00152587890625); // 100 / 65536 Pot
minPot = (buf[1] * 0.00152587890625); // 100 / 65536 Ground
maxPot = (buf[2] * 0.00152587890625); // 100 / 65536 3.3
buf.release();
}
kmV = 100 / (maxPot - minPot);
potPerc = (potPerc * kmV) - minPot;
if (potPerc < 0) {
potPerc = 0;
} else if (potPerc > 100) {
potPerc = 100;
}
}
/***************************************************/
/* Write constant text on display */
/***************************************************/
void writeLabel(char *buf, uint8_t s, int16_t x, int16_t y, int16_t color, int16_t bckg) {
display.setCursor(x, y);
display.setTextSize(s);
display.setTextColor(color, bckg);
display.println(buf);
}
/***************************************************/
/* Write variable text on display */
/***************************************************/
void writeValue(float val, char *dec, uint8_t s, int16_t x, int16_t y, int16_t color, int16_t bckg) {
char buf[15];
snprintf (buf, sizeof(buf), dec, val);
writeLabel(buf, s, x, y, color, bckg);
}
/***************************************************/
/* Refresh values on display */
/***************************************************/
static void refreshDisplay() {
writeLabel("Axis X: ", 6, 50, 30, green, black);
writeValue((encoderPulses*0.00125), "%.3f ", 6, 400, 30, green, black);
writeLabel("mm/s X: ", 6, 50, 110, green, black);
writeValue((feedSpeed), "%.3f ", 6, 400, 110, green, black);
writeLabel("Pos. X: ", 6, 50, 190, green, black);
writeValue((pwmInPulses*0.00125), "%.3f ", 6, 400, 190, green, black);
writeLabel("Freq X: ", 6, 50, 270, green, black);
writeValue(pwmFrequency, "%.0f ", 6, 400, 270, green, black);
writeLabel("Range : ", 6, 50, 350, green, black);
writeValue(feedRange, "%.0f ", 6, 400, 350, green, black);
}
/***************************************************/
/* MAIN LOOP */
/***************************************************/
void loop() {
readInputs();
watchdogRun();
refreshDisplay();
readPot();
setSpeedSelection();
generatePwm();
}
The GIGA DISPLAY should display five lines like these:
Axis X: 1234.567
mm/s X: 1.234
Pos. X: 987.654
Freq X: 100000
Range: 5
before the ":" are fixed text, after ":" dynamic text.
It was running perfectly until yesterday night
The SW is under development, not yet finished...some comment may be not correct..sorry for that