Nu fungerar den klockrent... har lyckats implemeterat min SQM-kod tillsammans med SGL's fokuserarkod, LCD, temp och manuell fokuskontroll
Här är koden, slänger kanske ut en youtubefilm på hur allt lirar när jag har mer tid för det.
Code: Select all
#include <MsTimer2.h>
#include <DHT.h>
#include <LiquidCrystal.h>
#include <SPI.h>
#include <FreqMeasure.h>
#include <Math.h>
LiquidCrystal lcd (12, 11, 10, 9, 7, 6);
//START OF FOCUS CONTROL INITIALISE
// include the library code:
#include <EEPROM.h>
#include <eepromRW.h>
#define MAX_COMMAND_LEN (5)
#define MAX_PARAMETER_LEN (6)
#define COMMAND_TABLE_SIZE (11)
#define TO_UPPER(x) (((x >= 'a') && (x <= 'z')) ? ((x) - ('a' - 'A')) : (x))
#define DHTPIN A3
#define DHTTYPE DHT22
// initialize the library with the numbers of the interface pins
int dirPin = 2; // Easy Driver Direction Output Pin
int stepperPin = 3; // EasyDriver Stepper Step Output Pin
int powerPin = 4; //Sets the output used to power the Driver board
unsigned long powerMillis = 0; // used to remember when EasyDriver power was enabled
int motorSteps =1600; //number if steps for the motor to turn 1 revolution
// MY OWN BUTTONCODE
int buttonIN = A0;
int buttonOUT = A1;
int val = 0;
// END OF MY OWN BUTTONCODE
// MY OWN DHT TO LCD-CODE
DHT dht(DHTPIN, DHTTYPE);
// END OF MY OWN DHT TO LCD-CODE
// MY OWN STEPS TO LCD-CODE
volatile long manualNoOfSteps;
// END OF MY OWN STEPS TO LCD-CODE
// MY OWN SQM-CODE
float Msqm;
const float A = 22.0;
int buttonSQM = A2;
int reading = 0;
int percentage = 0;
// END OF MY OWN SQM-CODE
volatile long NoOfSteps = 1000; //required number of steps to make
volatile long Position = 0; //used to keep track of the current motorposition
volatile long MaxStep = 200000; //define maximum no. of steps, max travel
volatile int SPEED = 200;
volatile byte MotorType = 0; // Motortypes, default is 0, Stepper motor, 1=Servo, 2=DC motor
volatile int BoardType = 0; // Boardtypes, default is 0, EasyDriver, 1=L293 chip, 2=LadyAda AFmotor board
boolean Direction = true;//True is one way false is other.Change to false if motor is moving in the wrong direction
boolean IsMoving = false;
boolean Absolute = true;
volatile long MaxIncrement=16384;//not yet used
//END OF FOCUS CONTROL INITIALISE
//Serial comms setup
char incomingByte = 0; // serial in data byte
byte serialValue = 0;
boolean usingSerial = true; // set to false to have the buttons control everything
char gCommandBuffer[MAX_COMMAND_LEN + 1];
char gParamBuffer[MAX_PARAMETER_LEN + 1];
long gParamValue;
volatile boolean UPDATE = true;
struct config_t //Memory Structure for Parking, Unparking the Focuser and other config settings
{
long parkposition;
boolean parked;
boolean stepperdirection;
long controlboardtype;
} configuration;
typedef struct {
char const *name;
void (*function)(void);
}
command_t;
//Set up a command table. when the command "IN" is sent from the PC and this table points it to the subroutine to run
command_t const gCommandTable[COMMAND_TABLE_SIZE] = {
{
"IN1", FocusINFun, }
,
{
"OUT", FocusOUTFun, }
,
{
"STP", FocusSTEPSFun, }
,
{
"SPD", FocusSPEEDFun, }
,
{
"LMT", FocusSLimitFun, }
,
{
"POS", FocusSPositionFun, }
,
{
"MDE", FocusSModeFun, }
,
{
"TYP", FocusSTypeFun, }
,
{
"PRK", ParkFocuserFun, }
,
{
"BRD", FocusBoardTypeFun, }
,
{
NULL, NULL }
};
//Serial Comms setup end
void setup() {
EEPROM_readAnything(0, configuration); //PARKING:- Read the Position and Parked info
if (configuration.parked == true) { //If the Focuser was Parked then load the Position information
Position = configuration.parkposition; //Load the Position information
Direction = configuration.stepperdirection;
BoardType = configuration.controlboardtype;
}
pinMode(dirPin, OUTPUT); //Initialise Easydriver output
pinMode(stepperPin, OUTPUT); //Initialise easy driver output
//START OF FOCUS CONTROL SETUP
//END OF FOCUS CONTROL SETUP
Serial.begin(19200);// start the serial
NoOfSteps=1000;
pinMode(13,OUTPUT);
pinMode(powerPin,OUTPUT); //Easydriver Sleep mode or power off
digitalWrite(powerPin, LOW); //Easydriver Pwer off (Low = powered down)
// MY OWN BUTTONCODE
pinMode(dirPin, OUTPUT);
pinMode(stepperPin, OUTPUT);
pinMode(buttonIN, INPUT);
digitalWrite(buttonIN, HIGH);
pinMode(buttonOUT, INPUT);
digitalWrite(buttonOUT, HIGH);
// END OF MY OWN BUTTONCODE
// MY OWN DHT TO LCD-CODE
lcd.begin(16,2);
dht.begin();
// END OF MY OWN DHT TO LCD-CODE
// MY OWN SQM-CODE
pinMode(buttonSQM, INPUT_PULLUP);
digitalWrite(buttonSQM, HIGH);
// END OF MY OWN SQM-CODE
}
// MY OWN SQM-CODE
double sum=0;
int count=0;
// END OF MY OWN SQM-CODE
void printStep(){
lcd.setCursor(6,0);
char s[7];
sprintf(s, "%7ld", manualNoOfSteps);
lcd.print(s);
MsTimer2::set(200, printStep);
MsTimer2::start();
}
void loop() {
int bCommandReady = false;
//FocuserControl Power off command
if (millis() > (powerMillis + 20000)) // check if power has been on for more than 20 seconds
{
digitalWrite(powerPin, LOW); // if yes, then disable power
}
//If There is information in the Serial buffer read it in and start the Build command subroutine
if (usingSerial && Serial.available() >= 1) {
// read the incoming byte:
incomingByte = Serial.read();
delay(5);
if (incomingByte == '#') {
// Build a new command. //
bCommandReady = cliBuildCommand(incomingByte);
}
}
else
{
incomingByte=0;
//Serial.flush();
}
//If there is a command in the buffer then run the process command subroutine
if (bCommandReady == true) {
bCommandReady = false; // reset the command ready flag
cliProcessCommand(); // run the command
}
if ((Position != configuration.parkposition)) {
configuration.parked = 0;
EEPROM_writeAnything(0, configuration);
}
if (UPDATE){
UPDATE=false;
SerialDATAFun(); // Used to send the current state of the focuser to the PC over serial comms
}
//MY OWN BUTTONCODE
//IN
lcd.setCursor(0,0);
lcd.print("Steps:");
delayMicroseconds(200);
val = digitalRead(buttonIN);
if (val == LOW)
{
digitalWrite(powerPin, HIGH);
digitalWrite(dirPin, HIGH);
MsTimer2::set(500, printStep);
MsTimer2::start();
while (val == LOW) {
digitalWrite(stepperPin, HIGH);
delayMicroseconds(200);
digitalWrite(stepperPin, LOW);
delayMicroseconds(200);
manualNoOfSteps = manualNoOfSteps + 1;
val = digitalRead(buttonIN);
}
MsTimer2::stop();
}
//OUT
delayMicroseconds(200);
val = digitalRead(buttonOUT);
if (val == LOW)
{
digitalWrite(powerPin, HIGH);
digitalWrite(dirPin, LOW);
MsTimer2::set(500, printStep);
MsTimer2::start();
while (val == LOW) {
digitalWrite(stepperPin, HIGH);
delayMicroseconds(200);
digitalWrite(stepperPin, LOW);
delayMicroseconds(200);
manualNoOfSteps = manualNoOfSteps - 1;
val = digitalRead(buttonOUT);
}
MsTimer2::stop();
}
// END OF MY OWN BUTTONCODE
// MY OWN DHT TO LCD-CODE
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
float t = dht.readTemperature();
// check if returns are valid, if they are NaN (not a number) then something went wrong!
if (isnan(t) || isnan(h)) {
lcd.setCursor(1,1);
lcd.println("Failed to read from DHT");
} else {
lcd.setCursor(9,1);
lcd.print(h);
lcd.print(" %");
lcd.setCursor(0,1);
lcd.print(t);
lcd.print((char)223);
lcd.print("C");
}
// END OF MY OWN DHT TO LCD-CODE
// MY OWN SQM-CODE
val = digitalRead(buttonSQM);
if (val == LOW) {
reading = 1;
lcd.clear();
FreqMeasure.begin();
while(reading) {
if (FreqMeasure.available()) {
// average several reading together
sum = sum + FreqMeasure.read();
count +=1;
percentage = count/31.0*100.0;
lcd.setCursor(0,0);
lcd.print("Reading");
lcd.setCursor(8,0);
lcd.print(percentage);
lcd.setCursor(11,0);
lcd.print("%");
if (count > 30) {
double frequency = F_CPU / (sum / count);
sum = 0;
count = 0;
Msqm = A - 2.5*log10(frequency); //Frequency to magnitudes/arcSecond2 formula
lcd.clear();
lcd.setCursor(0,0);
lcd.println("Mag/As2: ");
lcd.setCursor(9,0);
lcd.print(Msqm);
delay(5000);
lcd.clear();
reading = 0;
FreqMeasure.end();
}
}
}
}
}
// END OF MY OWN SQM-CODE
//***************************************************
//*****Start of User defined Functions **************
//***************************************************
//START OF FOCUS CONTROL FUNCTIONS
void EasyDriverStep(boolean dir,long steps){
digitalWrite(powerPin, HIGH); // enable power to the EasyDriver
powerMillis = millis(); // remember when power was switched on
delayMicroseconds(10); // wait a bit after switching on power
digitalWrite(dirPin,dir);
delay(100);
for(int i=0;i<steps;i++){
digitalWrite(stepperPin, HIGH);
delayMicroseconds(SPEED);
digitalWrite(stepperPin, LOW);
delayMicroseconds(SPEED);
}
}
void ParkFocuserFun (void) {//Park the focuser by setting the Park bit to 1 and the current Focuser Position in Configuration
if (configuration.parked == false){
configuration.parkposition = Position;
configuration.stepperdirection = Direction;
configuration.parked = true;
configuration.controlboardtype = BoardType;
EEPROM_writeAnything(0, configuration);
}
UPDATE=true; //Update even if the focuser was already parked
}
void FocusINFun (void) {//Move the Stepper IN.
long Steps = 0;
if (Absolute == false) { //If not Absolute move the number of steps
if ((Position-NoOfSteps)>=0) {
switch (BoardType) {
case 0:
EasyDriverStep(Direction,NoOfSteps);
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
Position=Position-NoOfSteps;
}
}
else if (NoOfSteps < MaxStep) //Absolute :- work out the number of steps to take based on current position
{
if (NoOfSteps<Position){
Steps=(Position-NoOfSteps);
switch (BoardType) {
case 0:
EasyDriverStep(Direction,Steps);
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
Position=NoOfSteps;
}
else
{
Steps=(NoOfSteps-Position);
switch (BoardType) {
case 0:
EasyDriverStep(!Direction,Steps);
break;
default:
break;
}
Position=NoOfSteps;
}
}
// set the update flag so that the new position is displayed
IsMoving=true;
UPDATE=true;
}
void FocusOUTFun (void) {//Move the Stepper OUT.
long Steps = 0;
if (Absolute == false) { //If not Absolute move the number of steps
if ((Position+NoOfSteps)<=MaxStep) {
switch (BoardType) {
case 0:
EasyDriverStep(!Direction,NoOfSteps);
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
Position=Position+NoOfSteps;
}
}
else if (NoOfSteps < MaxStep) //Absolute :- work out the number of steps to take based on current position
{
if (NoOfSteps>Position){
Steps=(NoOfSteps-Position);
switch (BoardType) {
case 0:
EasyDriverStep(!Direction,Steps);
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
Position=NoOfSteps;
}
else
{
Steps=(Position-NoOfSteps);
switch (BoardType) {
case 0:
EasyDriverStep(Direction,Steps);
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
Position=NoOfSteps;
}
}
// set the update flag so that the new position is displayed
IsMoving=true;
UPDATE=true;
}
void FocusSTEPSFun (void) {//Set the number of Steps.
NoOfSteps = gParamValue;
// set the update flag so that the new position is displayed
UPDATE=true;
}
// function to set the RPM of the stepper motor
// user sends :speed:500:
void FocusSPEEDFun (void) {
SPEED = gParamValue;
UPDATE=true;
}
// Set max limit for focus travel, for absolute positioning focusers
void FocusSLimitFun (void) {
MaxStep = gParamValue;
UPDATE=true;
}
// set current focuser position, used for calibrating absolute positioning focusers
void FocusSPositionFun (void) {
Position = gParamValue;
UPDATE=true;
}
// set the focuser mode to relative 0 or absolute positioning 1
void FocusSModeFun (void) {
switch (gParamValue){
case 0:
Absolute=false;
//Serial.println("Relative Mode"); // debug only
break;
case 1:
Absolute=true;
//Serial.println("Absolute Mode"); // debug only
break;
default:
//Serial.println("0 or 1 for relative or absolute, try again"); // debug only
break;
}
UPDATE=true;
}
// to add different motor types, stepper, servo or DC
void FocusSTypeFun(void){
MotorType=gParamValue;
UPDATE=true;
}
// to add different motor types, stepper, servo or DC
void FocusBoardTypeFun(void){
BoardType=gParamValue;
UPDATE=true;
}
//END OF FOCUS CONTROL FUNCTIONS
//Start of serial control functions
void SerialDATAFun (void) {//Update All information over comms if there has been any change in the state of the focuser
Serial.print("#POS:");
Serial.print(Position);
Serial.println(";");
Serial.print("#STP:" );
Serial.print(NoOfSteps);
Serial.println(";");
Serial.print("#MDE:");
if (Absolute){
Serial.print("1");
}
else{
Serial.print("0");
}
Serial.println(";");
Serial.print("#LMT:");
Serial.print(MaxStep);
Serial.println(";");
Serial.print("#SPD:");
if (SPEED==0){
Serial.print(char(SPEED));
}
else{
Serial.print(SPEED);
}
Serial.println(";");
if (IsMoving==true) {
Serial.print("#MOV:");
Serial.print("1");
Serial.println(";");
IsMoving=false;
}
Serial.print("#BRD:0");
Serial.print(BoardType);
Serial.println(";");
Serial.print("#PRK:");
if (configuration.parked == 1) Serial.print("01"); else Serial.print("00");
Serial.println(";");
}
//Process Command. This searches the command table to see if the command exits if it does then the required subroutine is run
void cliProcessCommand(void)
{
int bCommandFound = false;
int idx;
/* Convert the parameter to an integer value.
* If the parameter is emplty, gParamValue becomes 0. */
gParamValue = strtol(gParamBuffer, NULL, 0);
/* Search for the command in the command table until it is found or
* the end of the table is reached. If the command is found, break
* out of the loop. */
for (idx = 0; gCommandTable[idx].name != NULL; idx++) {
if (strcmp(gCommandTable[idx].name, gCommandBuffer) == 0) {
bCommandFound = true;
break;
}
}
/* If the command was found, call the command function. Otherwise,
* output an error message. */
if (bCommandFound == true) {
(*gCommandTable[idx].function)();
}
}
//When data is in the Serial buffer this subroutine is run and the information put into a command buffer.
// The character : is used to define the end of a Command string and the start of the parameter string
// The character ; is used to define the end of the Parameter string
int cliBuildCommand(char nextChar) {
static uint8_t idx = 0; //index for command buffer
static uint8_t idx2 = 0; //index for parameter buffer
int loopchk = 0;
nextChar = Serial.read();
do
{
gCommandBuffer[idx] = TO_UPPER(nextChar);
idx++;
nextChar = Serial.read();
loopchk=loopchk+1;
}
while ((nextChar != ':') && (loopchk < 100));
loopchk=0;
nextChar = Serial.read();
do
{
gParamBuffer[idx2] = nextChar;
idx2++;
nextChar = Serial.read();
}
while ((nextChar != ';')&& (idx2 < 100));
gCommandBuffer[idx] = '\0';
gParamBuffer[idx2] = '\0';
idx = 0;
idx2 = 0;
return true;
}
//END of serial control functions