Arduino

ruzne programy,konverze dat, digitalizace, atd...
HonzaHorka
Příspěvky: 1012
Registrován: 15. 11. 2009, 2:17

6. 11. 2018, 4:34

Mám 2 různé programy pro Arduino mega 2560 a potřeboval bych vyřešit aby se daly oba spouštět na jednom Arduinu, třeba tak že by se n některý PIN Arduina dal přepínač a dle úrovně na pinu 1 či 0 po zapnutí by se spustil jeden nebo druhý program. Bohužel s programováním nemám žádnou zkušenost a moc mi to do hlavy nejde. zvladam tak pouze upravit nějaké hodnoty. Pomohl by mi někdo?
Mex
Příspěvky: 10288
Registrován: 6. 2. 2014, 10:29

6. 11. 2018, 5:19

Asi těžko dostaneš univerzální odpověď.
Záleží na tom, co jsou to za programy - jestli je to něco velkého a kompexního (třeba něco jako GRBL) nebo naopak nějaká blbost typu klíkání LED. No a samozřejmě pak jestli to máš ve formě zdrojáků nebo jak.
HonzaHorka
Příspěvky: 1012
Registrován: 15. 11. 2009, 2:17

6. 11. 2018, 5:43

Chápu, jsou to docela jednoduché programy, jedno je v podstatě program pro ovládání delicky a druhý je zase jen pro řízení otáček delicky v různém převodovém poměru vůči vřetenu. Oba programy každý na několik stranek. Bohužel autoři jsou rusové tak ve zdojaku pozbamky v azbuce. Oba programy jsem pouze upravoval aby mi sedělo zapojení displeje a klávesnice na stejné piny.
Uživatelský avatar
Cjuz
Příspěvky: 2422
Registrován: 17. 2. 2013, 6:27
Bydliště: Předklášteří
Kontaktovat uživatele:

6. 11. 2018, 5:58

Bez přesné znalosti programu to nejde určit.
Můžeš načíst společně knihovny, případně pořešit proměné apod (pokud to dá paměť)
Hlavní smyčky pak zabalit do instrukce if, nebo while a kontrolovat při každém průchodu nějaký pin.
To je hodně primitivní.
Jenže tohle bude mít nějaké zpoždění a nemusí to být funkční.

Tedy šupni sem oba programy
Na konci poznávacího procesu je omyl zcela vyvrácen a my nevíme nic. Zato to víme správně.
HonzaHorka
Příspěvky: 1012
Registrován: 15. 11. 2009, 2:17

6. 11. 2018, 6:10

U PC budu až zítra, tet jsem na mobilu tak to pošlu.
HonzaHorka
Příspěvky: 1012
Registrován: 15. 11. 2009, 2:17

7. 11. 2018, 4:33

otočný stůl dělička:

/*
This works on the Uno
In this version I will modify step calculation
4x4 matrix keypad amd a 20 x 4 LCD.
Edit Rotation & TableRatio(# of turns for 360 degrees)in line 29
A4988 Stepstick/Pololu driver
5/2/2015
*/
// **************define Debug Macro**************
//#define DEBUG 1 //delete slashes for printing debug info to serial monitor
#ifdef DEBUG
#define DEBUG_Print(x) Serial.print(x)
#define DEBUG_PrintDec(x,y) Serial.print(x,y)
#define DEBUG_Println(x) Serial.println(x)
#else
#define DEBUG_Print(x)
#define DEBUG_PrintDec(x,y)
#define DEBUG_Println(x)
#endif

#include <Wire.h>
//#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <EEPROM.h>
const byte ROWS = 4;
const byte COLS = 4;
//****************USER DEFINED**************
//setup vars

int StepsPerRotation = 2376; // Set Steps per rotation of stepper NOTE the driver is set to Half step
int TableRatio = 10; // ratio of rotary table
int stepdelay = 1; //this is in microseconds
int delay1 = 200; //this is used for initial Splash Screen display time
const int delay2 = 500; //this is used for subsequent Splash screens
char key;

//**For pro micro
/* const int stp = 8; // connect pin D8 to step
const int dir = 9; // connect pin D9 to dir
byte colPINS[ROWS] = {18,19,20,21}; //pin 1 of keypad to pin 10
byte rowPINS[COLS] = {10,16,14,15};*/
//**************

///*for mega 2560 r3
const int stp = 49;
const int dir = 47;
const int enable = 45;
byte colPINS[ROWS] = {34,36,38,40}; //pin 1 of keypad to pin 12 //řádky
byte rowPINS[COLS] = {26,28,30,32}; //sloupce
//***************

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
//char LCD_Row_1[17];
//char LCD_Row_2[17];



//LiquidCrystal_I2C lcd(0x38,20,4); // set the LCD address as determined by I2C scanner
// SCL - 21, SDA - 20, VCC - +5, Gnd - Gnd
//***********************************************



int isteps, itable;

char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'.','0','#','D'}
};


Keypad kpd = Keypad(makeKeymap(keys),rowPINS,colPINS, ROWS, COLS);


int moved;
long Multiplier;


long cumSteps = 0;
float Degrees = 0.; // Degrees from keypad
long ToMove = 0; // Steps to move

float bob = 0.; //this tracks current position in degrees

int cho = 0;

void setup()
{
lcd.begin(20,4);
// lcd.init(); // initialize the lcd
// lcd.init(); // initialize the lcd
// lcd.backlight();
EEPROM.get(0,TableRatio);
EEPROM.get(2,StepsPerRotation);
EEPROM.get(4,stepdelay);


//from EEPROM
#ifdef DEBUG
Serial.begin(115200);
#endif

pinMode(stp, OUTPUT);
pinMode(dir, OUTPUT);

// Print welcome message to the LCD.

lcd.print("Rotary Table Control");

lcd.setCursor(3,3);
lcd.print("EEPROM 2018 beta2");
delay(delay1);



/*check if key pad A is held down if it is
* then jump to getRatios and input new rations
*/
int i=0;

key = kpd.getKey();



DEBUG_Print("EEPROM Table = "); DEBUG_Print(TableRatio);DEBUG_Println(":1");
DEBUG_Print("EEPROM Steps = "); DEBUG_Println(StepsPerRotation);
DEBUG_Print("EEPROM Deelay = "); DEBUG_Println(stepdelay);

delay1=delay2;
// lcd.init();
//*****************************************

cho = 0;
// *************************************************

key = kpd.getKey();
/* lcd.print("Enter Selection:");
lcd.setCursor(0,1);
lcd.print("Degrees = A");
lcd.setCursor(0,2);
lcd.print("Divisions = B");
lcd.setCursor(0,3);
lcd.print("JOG = C");*/


lcd.setCursor(0,0);
lcd.print("Degrees = A");
lcd.setCursor(0,1);
lcd.print("Divisions = B");
lcd.setCursor(0,2);
lcd.print("JOG = C");
lcd.setCursor(0,3);
lcd.print("Settings = D");
while(cho == 0)
{
key = kpd.getKey();
switch (key)
{
case NO_KEY:
break;
case 'A':
Degrees=getdegrees();
lcd.clear();

cho = 1;
break;
case 'B':
Degrees=getdivisions();
cho=2;
break;
case 'C':
Degrees=getjog();
lcd.clear();
cho=3;
break;
case 'D':
Settings();
EEPROM.get(0,TableRatio);
EEPROM.get(2,StepsPerRotation);
EEPROM.get(4,stepdelay);
lcd.clear();
cho=0;
lcd.setCursor(0,0);
lcd.print("Degrees = A");
lcd.setCursor(0,1);
lcd.print("Divisions = B");
lcd.setCursor(0,2);
lcd.print("JOG = C");
lcd.setCursor(0,3);
lcd.print("Settings = D");
break;

} // end case
} // end while cho=0

DEBUG_Print("Table Ratio = "); DEBUG_Println(TableRatio);
DEBUG_Print("Steps per Rotation = "); DEBUG_Println(StepsPerRotation);
Multiplier = (long)TableRatio * StepsPerRotation;
DEBUG_Print("Multiplier = "); DEBUG_Println(Multiplier);


} // end setup

void loop() // MAIN LOOP
{
lcd.clear();
char key = kpd.getKey();

bob = 0;

cumSteps=0;
lcd.setCursor(7,0);lcd.print("Total: ");lcd.print(" ");lcd.setCursor(14,0);lcd.print(bob,2); // total steps

lcd.setCursor(0,3);lcd.print("FOR=A REV=B X=C");
while(key != 'C') // C will return to start menu
{
lcd.setCursor(0,0);lcd.print(abs(Degrees),2);lcd.print((char)223);
key = kpd.getKey();
if (key !=NULL){DEBUG_Print("Key is ");DEBUG_Println(key);}
if(key == 'A') // FORWARD
{

bob = bob + Degrees;

ToMove=(long)((float)(bob/360 * Multiplier + 0.5 - cumSteps));

cumSteps=cumSteps+ToMove;

digitalWrite(dir, LOW);
printadvance();

}
if(key=='B') // REVERSE
{

bob = bob - Degrees;
ToMove=(long)((float)(cumSteps+0.5 - (bob * Multiplier)/360));

cumSteps=cumSteps-ToMove;




digitalWrite(dir, HIGH); // pin 13
printadvance();
}
} // end while not C loop
// lcd.init();
setup();
} // end main VOID



float getjog() // used to set mechanical ratio and steps per revelution
{
float Degrees = 0;
float num = 0.00;
char key = kpd.getKey();
lcd.clear();
lcd.setCursor(6,0);lcd.print("Jogging");
lcd.setCursor(0,1);lcd.print("A=1 B=5 C=25 Degrees");
lcd.setCursor(0,2);lcd.print("Choose Degrees:");lcd.setCursor(0,3);lcd.print("OK = # ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");

while(key != '#')
{
switch (key)
{
case NO_KEY:
break;
case 'A':
Degrees = 1;
lcd.setCursor(16,2);lcd.print(Degrees,1);
break;
case 'B':
Degrees = 5;
lcd.setCursor(16,2);lcd.print(Degrees,1);
break;
case 'C':
Degrees = 25;
lcd.setCursor(16,2);lcd.print(Degrees,1);
break;
case 'D':
num=0.00;
lcd.setCursor(15,2);lcd.print(" ");
lcd.setCursor(15,2);
break;
}
key = kpd.getKey();
}
return Degrees;
}


float getdivisions()
{
float Degrees = 0;
float num = 0.00;
char key = kpd.getKey();
lcd.clear();
lcd.setCursor(0,1);lcd.print("Enter Division:");
lcd.setCursor(0,3);lcd.print("OK = # ");
lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
lcd.setCursor(16,1);

while(key != '#')
{
switch (key)
{
case NO_KEY:
break;

case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
num = num * 10 + (key - '0');
lcd.print(key);
break;

case 'D':
num=0.00;
lcd.setCursor(16,1);lcd.print(" ");
lcd.setCursor(16,1);
break;
}
Degrees = (float)(360/num);
key = kpd.getKey();
}
return Degrees; //num;
}


float getdegrees()
{
//int key = 0;
float num = 0.00;
float decimal = 0.00;
float decnum = 0.00;
int counter = 0;
lcd.clear();
//lcd.init();
char key = kpd.getKey();
lcd.setCursor(0,1);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = # ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
lcd.setCursor(15,1);
bool decOffset = false;

while(key != '#')
{
switch (key)
{
case NO_KEY:
break;

case '.':
if(!decOffset)
{
decOffset = true;
}
lcd.print(key);
break;

case 'D':
num=0.00;
lcd.setCursor(15,1);lcd.print(" ");
lcd.setCursor(15,1);
break;

case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if(!decOffset)
{
num = num * 10 + (key - '0');
lcd.print(key);
}
else if((decOffset) && (counter <= 1))
{
num = num * 10 + (key - '0');
lcd.print(key);
counter++;
}
break;
} //end case
decnum = num / pow(10, counter);
key = kpd.getKey();
} //end while not #
return decnum;
} // end getdegrees

void printadvance() // print function
{
lcd.setCursor(6,1);lcd.print("Moving");
lcd.setCursor(4,2);lcd.print("Steps ");lcd.print(ToMove);lcd.setCursor(13,0); lcd.print(" ");
lcd.setCursor(14,0);lcd.print(bob,2);
rotation(ToMove,0);
lcd.setCursor(6,1);lcd.print(" ");
}

void rotation(long tm, int d)
{
DEBUG_Print("Total Degrees = "); DEBUG_PrintDec(bob,3); DEBUG_Print(" Steps to move = "); DEBUG_Print(tm); DEBUG_Print(" Total Steps = "); DEBUG_Println(cumSteps);

for(long i = 0; i < tm; i++)
{


digitalWrite(stp, HIGH);
delayMicroseconds(stepdelay);
digitalWrite(stp, LOW);
delayMicroseconds(stepdelay);
}


}

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile (" jmp 0");
}
// get first value Table Ratio

void Settings()
{

//first get Table Ratio
lcd.clear();
lcd.setCursor(0,0);lcd.print("TableRatio = ");
TableRatio = getInt(TableRatio);
DEBUG_Print("New Table = "); DEBUG_Print(TableRatio);DEBUG_Println(":1");

//Now get steps per Rev
lcd.clear();
lcd.setCursor(0,0);lcd.print("Steps per Rev = ");
StepsPerRotation = getInt(StepsPerRotation);
DEBUG_Print("New Steps = "); DEBUG_Println(StepsPerRotation);

//Now get step delay
lcd.clear();
lcd.setCursor(0,0);lcd.print("Step delay = ");
stepdelay = getInt(stepdelay);
DEBUG_Print("New Delay = "); DEBUG_Println(stepdelay);

lcd.clear();
EEPROM.put(0,TableRatio);
EEPROM.put(2,StepsPerRotation);
EEPROM.put(4,stepdelay);

}

int getInt(int curVal){
int newVal ;

lcd.print(curVal);
lcd.setCursor(0,1);lcd.print("New value ");
lcd.setCursor(0,3);lcd.print("OK = # ");
lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
lcd.setCursor(10,1);
delay(500);
newVal=0;

key = kpd.getKey();

while(key != '#')
{
switch (key)
{
case NO_KEY:
break;

case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
newVal = newVal* 10 + (key - '0');
lcd.print(key);
break;

case 'D':
newVal=0;
lcd.setCursor(9,1);lcd.print(" ");
lcd.setCursor(10,1);
break;
}
key = kpd.getKey();
}
if (newVal ==0)
{ newVal = curVal;}

DEBUG_Print("newVal = "); DEBUG_Println(newVal);
return newVal;
}
HonzaHorka
Příspěvky: 1012
Registrován: 15. 11. 2009, 2:17

7. 11. 2018, 4:35

otočný stůl odval:

#include <avr/pgmspace.h>


// ***** LCD *****
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
char LCD_Row_1[17];
char LCD_Row_2[17];


// ***** Stepper Motor *****
//#define Motor_X_Step_Per_Revolution 2400
//#define Motor_Y_Step_Per_Revolution 2400
#define MotorPort PORTL // под моторы выделен весь порт "L",
#define MotorInitialization() DDRL=B11111111 // сконфигурирован как выход
#define Motor_X_SetPulse() MotorPort &= ~(1<<0) // Pin49 1
#define Motor_X_RemovePulse() MotorPort |= (1<<0) // Pin49 0
#define Motor_Y_SetPulse() MotorPort &= ~(1<<1) // Pin48 1
#define Motor_Y_RemovePulse() MotorPort |= (1<<1) // Pin48 0
#define Motor_X_Forward() MotorPort |= (1<<2) // Pin47 0
#define Motor_X_Reverse() MotorPort &= ~(1<<2) // Pin47 1
#define Motor_Y_Forward() MotorPort |= (1<<3) // Pin46 0
#define Motor_Y_Reverse() MotorPort &= ~(1<<3) // Pin46 1
#define Motor_X_Enable() MotorPort |= (1<<4) // Pin45 0
#define Motor_X_Disable() MotorPort &= ~(1<<4) // Pin45 1
#define Motor_Y_Enable() MotorPort |= (1<<5) // Pin44 0
#define Motor_Y_Disable() MotorPort &= ~(1<<5) // Pin44 1
boolean Step_On_flag=false; // Флаг разрешаем/запрещаем счет до "шагать"
boolean Mode_On_flag=false; // Флаг On/Off режим


// ***** Taho *****
#define TahoPort PORTL
#define TahoSetPulse() TahoPort |= (1<<6) // Pin43 1
#define TahoRemovePulse() TahoPort &= ~(1<<6) // Pin43 0


// ***** Encoder *****
#define Enc_Line_per_Revolution 1800 // Кол-во линий энкодера
#define Enc_Line Enc_Line_per_Revolution*2 // Рабочее кол-во тиков
#define EncoderPort PORTD
#define EncoderInitialization() DDRD=B00000000 // Под энкодер выделен весь порт "D", сконфигурирован на вход
#define Enc_Read() (PIND & B00000010)
volatile int Enc_Pos=0; // Счетчик положения энкодера
volatile byte Ks_Count=0; // Счетчик для "Подача", "Резьба" целая часть
volatile int Km_Count=0; // Счетчик для "Подача", "Резьба" дробная часть
byte Ks_Divisor=0; // Делитель для "Подача", "Резьба" целая часть
int Km_Divisor=0; // Делитель для "Подача", "Резьба" дробная часть
int Enc_Pos_tmp=0;
long Spindle_Angle=0;


//***** Sensor *****
#define SensorPort PORTD
#define Sensor PIND
#define Sensor_Left_Mask B00001000
#define Sensor_Right_Mask B00000100
char Sensor_Mask = B00000000;


enum Pressed_Key
{
Key_None,
Key_Right,
Key_Up,
Key_Down,
Key_Left,
Key_Select
};
byte Pressed_Key=Key_None;
boolean key_flag=false; // флаг нажатой/отжатой кнопки


// ***** Mode *****
enum Mode
{
Mode_Thread_Left=1,
Mode_Feed_Left,
Mode_Divider,
Mode_Feed_Right,
Mode_Thread_Right
};
byte Mode = Mode_Divider;


// ***** Feeds *****
// Enc_Line/(Step_Per_Revolution/Feed_Screw*Feed_mm)
#define Total_Feeds 10 // Кол-во подач
typedef struct
{
byte s_Divisor; // Делитель для "Подача" целая часть
char Text[7];
}
FEED_INFO;
FEED_INFO Feed_Info[Total_Feeds] =
{
{ 113, "0.02mm" },
{ 56, "0.04mm" },
{ 38, "0.06mm" },
{ 28, "0.08mm" },
{ 23, "0.10mm" },
{ 19, "0.12mm" },
{ 16, "0.14mm" },
{ 14, "0.16mm" },
{ 13, "0.18mm" },
{ 11, "0.20mm" },
};
byte Feed_Step = 3; // выборка из массива по умолчанию (0.08mm)


// ***** Threads *****
// Enc_Line/(Step_Per_Revolution/Feed_Screw*Thread_mm)
#define Total_Threads 36 // Кол-во резьб
typedef struct
{
byte s_Divisor; // Делитель для "Резьба" целая часть
int m_Divisor; // Делитель для "Резьба" дробная часть
char Text[7];
}
THREAD_INFO;
THREAD_INFO Thread_Info[Total_Threads] =
{
{ 11, 2500, "0.20mm" },
{ 9, 0, "0.25mm" },
{ 7, 5000, "0.30mm" },
{ 6, 4286, "0.35mm" },
{ 5, 6250, "0.40mm" },
{ 4, 5000, "0.50mm" },
{ 3, 7500, "0.60mm" },
{ 3, 2143, "0.70mm" },
{ 3, 0, "0.75mm" },
{ 2, 8125, "0.80mm" },
{ 2, 2500, "1.00mm" },
{ 1, 8000, "1.25mm" },
{ 1, 5000, "1.50mm" },
{ 1, 2857, "1.75mm" },
{ 1, 1250, "2.00mm" },
{ 7, 866, "80tpi " },
{ 6, 3780, "72tpi " },
{ 5, 6693, "64tpi " },
{ 5, 3150, "60tpi " },
{ 4, 9606, "56tpi " },
{ 4, 2520, "48tpi " },
{ 3, 8976, "44tpi " },
{ 3, 5433, "40tpi " },
{ 3, 1890, "36tpi " },
{ 2, 8347, "32tpi " },
{ 2, 4803, "28tpi " },
{ 2, 3917, "27tpi " },
{ 2, 3032, "26tpi " },
{ 2, 1260, "24tpi " },
{ 1, 9488, "22tpi " },
{ 1, 7717, "20tpi " },
{ 1, 6831, "19tpi " },
{ 1, 5945, "18tpi " },
{ 1, 4173, "16tpi " },
{ 1, 2402, "14tpi " },
{ 1, 0630, "12tpi " },
};
byte Thread_Step = 10; // выборка из массива по умолчанию (1.0mm)


// ***** Interrupts *****
#define EnableINT0() EIMSK |= (1 << INT0)
#define DisableINT0() EIMSK &= ~(1 << INT0)
#define Init_INT0_Any() EICRA = B00000001


//*********************************************************
void setup()
{
TIMSK0=0; // !Отключаем таймер! (он что-то свое делает в фоновом режиме)

EncoderInitialization();
PORTD=B00001111; // подтяжка PIN_21, 20, 19, 18

MotorInitialization();
Init_INT0_Any();
EnableINT0();

lcd.begin(16, 2);
}


//**********************************************************
void loop()
{
Enc_Pos_tmp = Enc_Pos; // в "void Divider" читаем повторно и сравниваем

if ((Mode == Mode_Divider) || !Mode_On_flag)
{
Motor_X_Disable();
// Motor_Y_Disable();
}
else
{
Motor_X_Enable();
// Motor_Y_Enable();
}

menu();
Sensors();
}


// ********** Функция обработки событий в главном меню **********
void menu()
{
int ADC_value = analogRead(A0);
if (ADC_value < 65) Pressed_Key=Key_Right;
else if (ADC_value < 220) Pressed_Key=Key_Up;
else if (ADC_value < 390) Pressed_Key=Key_Down;
else if (ADC_value < 600) Pressed_Key=Key_Left;
else if (ADC_value < 870) Pressed_Key=Key_Select;
else Pressed_Key = Key_None;

if (!key_flag)
{
switch (Pressed_Key)
{
case Key_Left:
MenuKeyLeftPressed();
break;
case Key_Right:
MenuKeyRightPressed();
break;
case Key_Up:
MenuKeyUpPressed();
break;
case Key_Down:
MenuKeyDownPressed();
break;
case Key_Select:
MenuKeySelectPressed();
break;
}
}
if (Pressed_Key == Key_None) key_flag = false;

SelectWorkMode(); // вызов выбранного рабочего режима
}

// ********** Обработчик нажатия кнопки Select **********
void MenuKeySelectPressed()
{
switch (Mode)
{
case Mode_Thread_Left:
case Mode_Thread_Right:
case Mode_Feed_Left:
case Mode_Feed_Right:
Step_On_flag = false;
Mode_On_flag = !Mode_On_flag; // переворачиваем значение на противоположное
Ks_Count = 0;
Km_Count = 0;
break;
case Mode_Divider:
Enc_Pos=0;
break;
}
key_flag = true;
}

// ********** Обработчик нажатия кнопки Up **********
void MenuKeyUpPressed()
{
switch (Mode)
{
case Mode_Thread_Left:
case Mode_Thread_Right:
if (Thread_Step < Total_Threads-1)
{
Mode_On_flag = false;
Step_On_flag = false;
Ks_Count=0;
Km_Count=0;
Thread_Step++;
}
break;
case Mode_Feed_Left:
case Mode_Feed_Right:
if (Feed_Step < Total_Feeds-1)
{
Ks_Count=0;
Feed_Step++;
}
break;
}
key_flag = true;
}

// ********** Обработчик нажатия кнопки Down **********
void MenuKeyDownPressed()
{
switch (Mode)
{
case Mode_Thread_Left:
case Mode_Thread_Right:
if (Thread_Step > 0)
{
Mode_On_flag = false;
Step_On_flag = false;
Ks_Count=0;
Km_Count=0;
Thread_Step--;
}
break;
case Mode_Feed_Left:
case Mode_Feed_Right:
if (Feed_Step > 0)
{
Ks_Count=0;
Feed_Step--;
}
break;
}
key_flag = true;
}

// ********** Обработчик нажатия кнопки Left **********
void MenuKeyLeftPressed()
{
switch (Mode)
{
case Mode_Feed_Left:
case Mode_Divider:
case Mode_Feed_Right:
case Mode_Thread_Right:
Mode_On_flag = false;
Step_On_flag = false;
Ks_Count=0;
Km_Count=0;
Mode--;
break;
}

key_flag = true;
}

// ********** Обработчик нажатия кнопки Right **********
void MenuKeyRightPressed()
{
switch (Mode)
{
case Mode_Thread_Left:
case Mode_Feed_Left:
case Mode_Divider:
case Mode_Feed_Right:
Mode_On_flag = false;
Step_On_flag = false;
Ks_Count=0;
Km_Count=0;
Mode++;
break;
}

key_flag = true;
}

// ********** Выбор режима работы **********
void SelectWorkMode()
{
switch (Mode)
{
case Mode_Thread_Left:
Thread_Left();
break;
case Mode_Feed_Left:
Motor_X_Reverse();
Feed_Left();
break;
case Mode_Divider:
Divider();
break;
case Mode_Feed_Right:
Motor_X_Forward();
Feed_Right();
break;
case Mode_Thread_Right:
Thread_Right();
}
}


//***************************************
void Thread_Left()
{
Sensor_Mask = Sensor_Left_Mask;
Ks_Divisor=Thread_Info[Thread_Step].s_Divisor;
Km_Divisor=Thread_Info[Thread_Step].m_Divisor;
snprintf(LCD_Row_1, 17, (Mode_On_flag==true) ? "Mode: ON " : "Mode: OFF ");
snprintf(LCD_Row_2, 17, "Thread <= %s", Thread_Info[Thread_Step].Text);
Print();
}

void Feed_Left()
{
Sensor_Mask = Sensor_Left_Mask;
Ks_Divisor=Feed_Info[Feed_Step].s_Divisor;
snprintf(LCD_Row_1, 17, (Mode_On_flag==true) ? "Mode: ON " : "Mode: OFF ");
snprintf(LCD_Row_2, 17, "Feed <= %s", Feed_Info[Feed_Step].Text);
Print();
}

void Divider()
{
if (Enc_Pos == Enc_Pos_tmp)
{
Spindle_Angle=(Enc_Pos*360000/(Enc_Line));
}
snprintf(LCD_Row_1, 17, "Mode: Divider ");
snprintf(LCD_Row_2, 17, "Angle: %3ld.%03ld ", Spindle_Angle/1000, Spindle_Angle%1000);
Print();
}

void Feed_Right()
{
Sensor_Mask = Sensor_Right_Mask;
Ks_Divisor=Feed_Info[Feed_Step].s_Divisor;
snprintf(LCD_Row_1, 17, (Mode_On_flag==true) ? "Mode: ON " : "Mode: OFF ");
snprintf(LCD_Row_2, 17, "Feed => %s", Feed_Info[Feed_Step].Text);
Print();
}

void Thread_Right()
{
Sensor_Mask = Sensor_Right_Mask;
Ks_Divisor=Thread_Info[Thread_Step].s_Divisor;
Km_Divisor=Thread_Info[Thread_Step].m_Divisor;
snprintf(LCD_Row_1, 17, (Mode_On_flag==true) ? "Mode: ON " : "Mode: OFF ");
snprintf(LCD_Row_2, 17, "Thread => %s", Thread_Info[Thread_Step].Text);
Print();
}


//******************************************************************
void Print()
{
lcd.setCursor(0, 0);
lcd.print(LCD_Row_1);
lcd.setCursor(0, 1);
lcd.print(LCD_Row_2);
}


//******************************************************************
void Sensors()
{
if (!(Sensor & Sensor_Mask) )
{
Mode_On_flag = false;
}
}


//******************************************************************
ISR(INT0_vect)
{
TahoRemovePulse();
Motor_X_RemovePulse();

if (!Enc_Read()) // Вращение шпинделя вправо
{
Enc_Pos++;
if (Enc_Pos == Enc_Line) // полный оборот
{
Enc_Pos = 0;
TahoSetPulse(); // при проходе 0 генерим сигнал Taho
Step_On_flag = (Mode_On_flag == true); // проверка режима на ON/OFF, только! после прохода 0 разрешаем счет до к.деления
}


if (Step_On_flag)
{
if (!(Sensor & Sensor_Mask) )
{
Step_On_flag = false;
return;
}

if (Mode == Mode_Feed_Left)
{
if (Ks_Count == Ks_Divisor)
{
Motor_X_SetPulse();
Ks_Count = 0;
}
Ks_Count++;
}

else if (Mode == Mode_Feed_Right)
{
if (Ks_Count == Ks_Divisor)
{
Motor_X_SetPulse();
Ks_Count = 0;
}
Ks_Count++;
}

else if (Mode == Mode_Thread_Left)
{
if (Ks_Count > Ks_Divisor)
{
Motor_X_Reverse();
Motor_X_SetPulse();
Km_Count = Km_Count + Km_Divisor;
if (Km_Count > Km_Divisor)
{
Km_Count = Km_Count - 10000;
Ks_Count = 0;
}
else
{
Ks_Count = 1;
}
}
Ks_Count++;
}

else if (Mode == Mode_Thread_Right)
{
if (Ks_Count > Ks_Divisor)
{
Motor_X_Forward();
Motor_X_SetPulse();
Km_Count = Km_Count + Km_Divisor;
if (Km_Count > Km_Divisor)
{
Km_Count = Km_Count - 10000;
Ks_Count = 0;
}
else
{
Ks_Count = 1;
}
}
Ks_Count++;
}
}
}


else
{ // Вращение шпинделя влево
Enc_Pos--;
if (Enc_Pos < 0)
{
Enc_Pos = Enc_Line - 1;
TahoSetPulse();
Step_On_flag = (Mode_On_flag == true); // проверка режима на ON/OFF, только! после прохода 0 разрешаем счет до к.деления
}

if (Step_On_flag)
{
if (!(Sensor & Sensor_Mask) )
{
Step_On_flag = false;
return;
}

if (Mode == Mode_Feed_Left)
{
if (Ks_Count == 0)
{
Motor_X_SetPulse();
Ks_Count = Ks_Divisor;
}
Ks_Count--;
}

if (Mode == Mode_Feed_Right)
{
if (Ks_Count == 0)
{
Motor_X_SetPulse();
Ks_Count = Ks_Divisor;
}
Ks_Count--;
}

if (Mode == Mode_Thread_Left)
{
if (Ks_Count == 0)
{
Motor_X_Forward();
Motor_X_SetPulse();
Km_Count = Km_Count - Km_Divisor;
if (Km_Count < 1)
{
Km_Count = Km_Count + 10000;
Ks_Count = Ks_Divisor + 1;
}
else
{
Ks_Count = Ks_Divisor;
}
}
Ks_Count--;
}

if (Mode == Mode_Thread_Right)
{
if (Ks_Count == 0)
{
Motor_X_Reverse();
Motor_X_SetPulse();
Km_Count = Km_Count - Km_Divisor;
if (Km_Count < 1)
{
Km_Count = Km_Count + 10000;
Ks_Count = Ks_Divisor + 1;
}
else
{
Ks_Count = Ks_Divisor;
}
}
Ks_Count--;
}
}
}
}

//*******************************************************************
HonzaHorka
Příspěvky: 1012
Registrován: 15. 11. 2009, 2:17

7. 11. 2018, 5:51

Tak se mi povedlo nahrát oba dva programy.
Uživatelský avatar
Cjuz
Příspěvky: 2422
Registrován: 17. 2. 2013, 6:27
Bydliště: Předklášteří
Kontaktovat uživatele:

7. 11. 2018, 6:24

Prvně si je sem mohl dát v textovém souboru :)
Za druhé nejsem žádný profík, je to jen názor jak bych to řešil já.


Jinak v děličce je hlavní smička void loop() // MAIN LOOP v otočném stolu void loop().
Takže bych z těchto smyček udělal podprogramy, například void delicka a void otocnystul.

V hlavní části void loop bych udělal jen výběr podle potřeby a volal bych co je potřeba.
Třeba podle stavu nějakého pinu.

No a to co je nejhorší, že se ti nesmí nic duplovat.
Takže musíš projít celé deklarace na začátku, aby si programy nealokovali stejné piny nebo proměnné.
Pokud ano je třeba název sjednotit.

A pokud ve smyčce void setup je opět duplicita tak se musí vyřešit, nebo udělat rozhodnutí i tam.

Ale nejspíše by to mělo jít.
Na konci poznávacího procesu je omyl zcela vyvrácen a my nevíme nic. Zato to víme správně.
Uživatelský avatar
Mr. MR
Příspěvky: 755
Registrován: 31. 5. 2020, 10:05

6. 10. 2020, 8:20

Čau,
snažím se napsat nějaký program, kde už si nevystačím s prvními lekcemi arduina ve stylu "blink" a podobně. Chtěl bych používat "class" a zjistil jsem, že dobře napsaných instruktáží je málo, alespoň já jsem je nechápal. Zatím se mi zdá, že tady
https://paulmurraycbr.github.io/ArduinoTheOOWay.html
je to dost dobře podané, ještě jsem to nedočetl a nevyzkoušel. Víte někdo o nějakém dalším dobrém zdroji informací o OOP pro arduino?
Připrav se, hrajem...
https://www.youtube.com/watch?v=HzjNAnEfvxc
lubbez
Příspěvky: 3148
Registrován: 21. 6. 2012, 9:26
Bydliště: Praha

6. 10. 2020, 8:53

Vidíš a já žiju minimálně 30 let v bludu, že objektově orientované programování není u jednočipů žádná výhra. Minimálně dva mí kolegové, co se živí profi programováním hardware jsou stejného názoru.
Mex
Příspěvky: 10288
Registrován: 6. 2. 2014, 10:29

6. 10. 2020, 8:58

lubbez píše: 6. 10. 2020, 8:53 Vidíš a já žiju minimálně 30 let v bludu, že objektově orientované programování není u jednočipů žádná výhra. Minimálně dva mí kolegové, co se živí profi programováním hardware jsou stejného názoru.
Já jsem další.
Josef
Sponzor fora
Příspěvky: 5699
Registrován: 19. 11. 2006, 9:25
Bydliště: Valašsko

6. 10. 2020, 11:56

Docela by mne zajímalo jaký je rozdíl délky výsledného kódu po kompilaci u strukturovaného a objektového zdrojáku, který dělá totéž (funkčně). Přiznám se, že mne ani ve snu nenapadlo na Arduinu zkoušet OOP.
Mex
Příspěvky: 10288
Registrován: 6. 2. 2014, 10:29

7. 10. 2020, 12:52

Josef píše: 6. 10. 2020, 11:56 Docela by mne zajímalo jaký je rozdíl délky výsledného kódu po kompilaci u strukturovaného a objektového zdrojáku, který dělá totéž (funkčně). Přiznám se, že mne ani ve snu nenapadlo na Arduinu zkoušet OOP.
No celý SW Arduino je objektový.
Když použiješ
Serial.begin(9600);
tak voláš metodu "begin" objektu "Serial".

U dobrého kompilátoru rozdíl moc velký nebude. Samozřejmě jde o to, jak to objektové programování budeš používat. I v objektovém C++ se dá psát neobjektově, a naopak v neobjektovém C se zase dá psát víceméně objektově.
Kompilátor Arduina je přiohnuté C++. Před vlastním překladem se tam jen preprocesorem změní ty podivnosti jako "setup()" a "loop()" na běžnou strukturu programu, doplní se implicitní definice a deklarace, připojí defaultní moduly atd.
Uživatelský avatar
Mr. MR
Příspěvky: 755
Registrován: 31. 5. 2020, 10:05

7. 10. 2020, 7:18

Jde mi o to, že chci pomocí arduina dělat více věcí současně a pochopil jsem, že správný přístup je OOP. Právě že mi taky přijde, že je OOP na to co potřebuju overkill. Chtěl bych měřit teplotu, tu vyhodnotit pomocí PID a topit, současně hlídat tlačítka a několik čidel. Všechno pak ještě v nějakém časovém plánu.

Řeknu příklad:
přístroj je zapnutý,
tlačítkem odstartuju program,
zapne se topení s PID,
až dojde k ustálení teploty zapnu další věci, většinou s různým spožděním,
pomocí čidel sleduju probíhající proces
pokud nastane chyba proces ukončím
pokud stisknu tlačítko, proces ukončím
proces po ukončení stále potřebuje dochlazení, takže je stále co hlídat
o všech procesech informace na LCD

Nechci se utopit v kilometrovém kódu, proto bych chtěl oddělit jednotlivé úkoly a proměnné.
Chtěl bych mít PID extra, časování jednotlivých procesů extra, informace na LCD extra, a ještě by bylo fajn mít možnost si pro odladění vypisovat data na seriový port, abych věděl, jak se co chová. Zkusil jsem, že hodně jde udělat s funkcemi, nicméně z funkce nedostanu více, než jednu proměnnou (mám na to použít struktury?).

Hodně také pomáhají záložky, kdy si kód rozdělím - každou funkci na jednu záložku. Navíc se mi líbí myšlenka, že si v jednom programu "vymazlím" třeba to PID, a pak to budu používat v různých projektech a nebudu do toho už muset rýt, prostě jen zadám, odkud bere informace o teplotě, kterým pinem spíná topení a odladím si konstanty. Děsím se, že bych musel neustále kvůli drobnostem procházet celý kód. Navíc jedntlivé funkce budu přidávat postupně a chtěl bych je mít odladěné, optimálně kažkou zvlášť.

Vymýšlím blbost? Jak se to dělá správně?
Připrav se, hrajem...
https://www.youtube.com/watch?v=HzjNAnEfvxc
Odpovědět

Zpět na „Ostatní software“