19-04-2024, 08:29
Witam
Mam problem mianowicie chodzi o to że po włączeniu silnika krokowego zamraża się ekran co jest nie tak coś z timereami ?
Pozdrawiam
#include <PID_v1_bc.h>
#include <thermistor.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define initialTemp 180
#define minTemp 180
#define maxTemp 230
#define initialSpeed 10
#define minSpeed 1
#define maxSpeed 50
#define initialMot 0
#define minMot 0
#define maxMot 2
int encLowLim = minTemp;
int encHighLim = maxTemp;
int encIncrement = 1;
int encCurrent = initialTemp;
int dataInputNo = 0;
static int pinA = 2;
static int pinB = 3;
volatile int encoderPos = initialTemp;
volatile int prevEncoderPos = initialTemp;
byte oldButtonState = HIGH;
const unsigned long debounceTime = 10;
unsigned long buttonPressTime;
boolean pressed = false;
const int temperaturePin = A0;
const int pwmPin = 5;
const int enablePin = 8;
const int motDirPin = 4;
const int motStepPin = 9;
const int encButton = 12;
int loopTime = 500;
unsigned long currentTime = 0;
double Kp = 80.0;
double Ki = 35.0;
double Kd = 80.0;
thermistor therm1(temperaturePin,0);
double setpoint = initialTemp;
double input, output;
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);
int motSpeed = initialSpeed;
int motDir = initialMot;
int motMaxDelay = 100;
int motDelayTime = 500;
void setup()
{
Serial.begin(9600);
pinMode(6, OUTPUT);
digitalWrite(6, HIGH);
//SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;; // Don't proceed, loop forever
}
display.clearDisplay();
pinMode(pwmPin, OUTPUT);
pid.SetMode(AUTOMATIC);
pid.SetOutputLimits(0, 255);
input = therm1.analog2temp();
pinMode(pinA, INPUT);
pinMode(pinB, INPUT);
attachInterrupt(digitalPinToInterrupt(pinA), rotaryInterrupt, CHANGE);
attachInterrupt(digitalPinToInterrupt(pinB), rotaryInterrupt, CHANGE);
pinMode(encButton, INPUT_PULLUP);
pinMode(motDirPin, OUTPUT);
pinMode(motStepPin, OUTPUT);
digitalWrite(motDirPin, HIGH);
Serial.println("Setup complete");
}
void loop()
{
currentTime = millis();
input = therm1.analog2temp();
pid.Compute();
analogWrite(pwmPin, output);
int temp = input;
Serial.print("Temperature: ");
Serial.print(temp);
Serial.print(" \u00B0C");
Serial.print("\tPWM Output: ");
Serial.print(output);
Serial.print("\tEncoder: ");
Serial.println(encCurrent);
updateDataDisplay ();
while(millis() < currentTime + loopTime)
{
byte buttonState = digitalRead (encButton);
if (buttonState != oldButtonState)
{
Serial.println("Button change");
if (millis () - buttonPressTime >= debounceTime)
{
buttonPressTime = millis ();
oldButtonState = buttonState;
if (buttonState == LOW)
{
pressed = true;
Serial.println("Button Pressed");
}
else
{
if (pressed == true)
{
boolean pressed = false;
Serial.println("Button Released");
if (dataInputNo == 0)
{
dataInputNo = 1;
encCurrent = motSpeed;
encLowLim = minSpeed;
encHighLim = maxSpeed;
}
else if (dataInputNo == 1)
{
dataInputNo = 2;
encCurrent = motDir;
encLowLim = minMot;
encHighLim = maxMot;
}
else
{
dataInputNo = 0;
encCurrent = setpoint;
encLowLim = minTemp;
encHighLim = maxTemp;
}
}
}
}
}
//Set the parameter being edited equal to the current encoder position
if (dataInputNo == 0)
{
setpoint = encCurrent;
}
else if (dataInputNo == 1)
{
motSpeed = encCurrent;
motDelayTime = 100 * (1 + maxSpeed - motSpeed);
}
else
{
motDir = encCurrent;
}
//Set the motor direction
if (motDir == 0)
{
pinMode(enablePin, OUTPUT);
digitalWrite(motDirPin, LOW);
updateDataDisplay ();
}
else if (motDir == 2)
{
pinMode(enablePin, OUTPUT);
digitalWrite(motDirPin, HIGH);
updateDataDisplay ();
}
else
{
pinMode(enablePin, INPUT);
}
//Pulse the stepper motor if forward or reverse is selected
while (motDir != 1)
{
runMotor ();
motDir = encCurrent;
}
}
}
//Increment the current setting if the rotary encoder is turned
void rotaryInterrupt ()
{
encoderPos = digitalRead(pinA);
if ((prevEncoderPos == 0) && (encoderPos == 1))
{
if (digitalRead(pinB) == 1)
{
if (encCurrent < encHighLim)
encCurrent=encCurrent+encIncrement;
}
else
{
if (encCurrent > encLowLim)
encCurrent=encCurrent-encIncrement;
}
}
prevEncoderPos = encoderPos;
delay(1);
}
//Update the OLED display contents
void updateDataDisplay ()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(2,10);
display.print(F("Aktualna Temp: "));
display.setCursor(2,20);
display.print(F("Zadana Temp: "));
display.setCursor(2,30);
display.print(F("Predkosc : "));
display.setCursor(2,40);
display.print(F("Silnik: "));
int temp = input;
int setPointInt = setpoint;
int selected = 0;
if (dataInputNo == 0)
{
selected = 20;
}
else if (dataInputNo == 1)
{
selected = 30;
}
else
{
selected = 40;
}
display.setCursor(87,selected);
display.print(F(">"));
display.setCursor(97,10);
display.print(temp);
display.print(F("C"));
display.setCursor(97,20);
display.print(setPointInt);
display.print(F("C"));
display.setCursor(97,30);
display.print(motSpeed);
display.setCursor(97,40);
if (motDir == 0)
display.print(F("TYL"));
else if (motDir == 2)
display.print(F("PRZOD"));
else
display.print(F("WYL"));
display.display();
}
//Turn the reel motor and maintain hot end temperature
void runMotor ()
{
digitalWrite(motStepPin, HIGH);
delayMicroseconds(motDelayTime);
digitalWrite(motStepPin, LOW);
if(millis() < currentTime + loopTime)
{
delayMicroseconds(motDelayTime);
}
else
{
//Record the start time for the loop
currentTime = millis();
//Read the temperature
input = therm1.analog2temp();
//Compute the PID output
pid.Compute();
//Update the PWM output
analogWrite(pwmPin, output);
}
}
Mam problem mianowicie chodzi o to że po włączeniu silnika krokowego zamraża się ekran co jest nie tak coś z timereami ?
Pozdrawiam
#include <PID_v1_bc.h>
#include <thermistor.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define initialTemp 180
#define minTemp 180
#define maxTemp 230
#define initialSpeed 10
#define minSpeed 1
#define maxSpeed 50
#define initialMot 0
#define minMot 0
#define maxMot 2
int encLowLim = minTemp;
int encHighLim = maxTemp;
int encIncrement = 1;
int encCurrent = initialTemp;
int dataInputNo = 0;
static int pinA = 2;
static int pinB = 3;
volatile int encoderPos = initialTemp;
volatile int prevEncoderPos = initialTemp;
byte oldButtonState = HIGH;
const unsigned long debounceTime = 10;
unsigned long buttonPressTime;
boolean pressed = false;
const int temperaturePin = A0;
const int pwmPin = 5;
const int enablePin = 8;
const int motDirPin = 4;
const int motStepPin = 9;
const int encButton = 12;
int loopTime = 500;
unsigned long currentTime = 0;
double Kp = 80.0;
double Ki = 35.0;
double Kd = 80.0;
thermistor therm1(temperaturePin,0);
double setpoint = initialTemp;
double input, output;
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);
int motSpeed = initialSpeed;
int motDir = initialMot;
int motMaxDelay = 100;
int motDelayTime = 500;
void setup()
{
Serial.begin(9600);
pinMode(6, OUTPUT);
digitalWrite(6, HIGH);
//SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;; // Don't proceed, loop forever
}
display.clearDisplay();
pinMode(pwmPin, OUTPUT);
pid.SetMode(AUTOMATIC);
pid.SetOutputLimits(0, 255);
input = therm1.analog2temp();
pinMode(pinA, INPUT);
pinMode(pinB, INPUT);
attachInterrupt(digitalPinToInterrupt(pinA), rotaryInterrupt, CHANGE);
attachInterrupt(digitalPinToInterrupt(pinB), rotaryInterrupt, CHANGE);
pinMode(encButton, INPUT_PULLUP);
pinMode(motDirPin, OUTPUT);
pinMode(motStepPin, OUTPUT);
digitalWrite(motDirPin, HIGH);
Serial.println("Setup complete");
}
void loop()
{
currentTime = millis();
input = therm1.analog2temp();
pid.Compute();
analogWrite(pwmPin, output);
int temp = input;
Serial.print("Temperature: ");
Serial.print(temp);
Serial.print(" \u00B0C");
Serial.print("\tPWM Output: ");
Serial.print(output);
Serial.print("\tEncoder: ");
Serial.println(encCurrent);
updateDataDisplay ();
while(millis() < currentTime + loopTime)
{
byte buttonState = digitalRead (encButton);
if (buttonState != oldButtonState)
{
Serial.println("Button change");
if (millis () - buttonPressTime >= debounceTime)
{
buttonPressTime = millis ();
oldButtonState = buttonState;
if (buttonState == LOW)
{
pressed = true;
Serial.println("Button Pressed");
}
else
{
if (pressed == true)
{
boolean pressed = false;
Serial.println("Button Released");
if (dataInputNo == 0)
{
dataInputNo = 1;
encCurrent = motSpeed;
encLowLim = minSpeed;
encHighLim = maxSpeed;
}
else if (dataInputNo == 1)
{
dataInputNo = 2;
encCurrent = motDir;
encLowLim = minMot;
encHighLim = maxMot;
}
else
{
dataInputNo = 0;
encCurrent = setpoint;
encLowLim = minTemp;
encHighLim = maxTemp;
}
}
}
}
}
//Set the parameter being edited equal to the current encoder position
if (dataInputNo == 0)
{
setpoint = encCurrent;
}
else if (dataInputNo == 1)
{
motSpeed = encCurrent;
motDelayTime = 100 * (1 + maxSpeed - motSpeed);
}
else
{
motDir = encCurrent;
}
//Set the motor direction
if (motDir == 0)
{
pinMode(enablePin, OUTPUT);
digitalWrite(motDirPin, LOW);
updateDataDisplay ();
}
else if (motDir == 2)
{
pinMode(enablePin, OUTPUT);
digitalWrite(motDirPin, HIGH);
updateDataDisplay ();
}
else
{
pinMode(enablePin, INPUT);
}
//Pulse the stepper motor if forward or reverse is selected
while (motDir != 1)
{
runMotor ();
motDir = encCurrent;
}
}
}
//Increment the current setting if the rotary encoder is turned
void rotaryInterrupt ()
{
encoderPos = digitalRead(pinA);
if ((prevEncoderPos == 0) && (encoderPos == 1))
{
if (digitalRead(pinB) == 1)
{
if (encCurrent < encHighLim)
encCurrent=encCurrent+encIncrement;
}
else
{
if (encCurrent > encLowLim)
encCurrent=encCurrent-encIncrement;
}
}
prevEncoderPos = encoderPos;
delay(1);
}
//Update the OLED display contents
void updateDataDisplay ()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(2,10);
display.print(F("Aktualna Temp: "));
display.setCursor(2,20);
display.print(F("Zadana Temp: "));
display.setCursor(2,30);
display.print(F("Predkosc : "));
display.setCursor(2,40);
display.print(F("Silnik: "));
int temp = input;
int setPointInt = setpoint;
int selected = 0;
if (dataInputNo == 0)
{
selected = 20;
}
else if (dataInputNo == 1)
{
selected = 30;
}
else
{
selected = 40;
}
display.setCursor(87,selected);
display.print(F(">"));
display.setCursor(97,10);
display.print(temp);
display.print(F("C"));
display.setCursor(97,20);
display.print(setPointInt);
display.print(F("C"));
display.setCursor(97,30);
display.print(motSpeed);
display.setCursor(97,40);
if (motDir == 0)
display.print(F("TYL"));
else if (motDir == 2)
display.print(F("PRZOD"));
else
display.print(F("WYL"));
display.display();
}
//Turn the reel motor and maintain hot end temperature
void runMotor ()
{
digitalWrite(motStepPin, HIGH);
delayMicroseconds(motDelayTime);
digitalWrite(motStepPin, LOW);
if(millis() < currentTime + loopTime)
{
delayMicroseconds(motDelayTime);
}
else
{
//Record the start time for the loop
currentTime = millis();
//Read the temperature
input = therm1.analog2temp();
//Compute the PID output
pid.Compute();
//Update the PWM output
analogWrite(pwmPin, output);
}
}