А ежли как я, фома не верующий?
ну ты жеж веришь, что вино должно получиться? )))
Нельзя так глубоко рыть.
Верю. Только если придерживаться технологии, а не абы как.
До этого с рук сходило, а тут…(
то-есть перекись льёшь?
видео с последними изменениями , пришлось мягкую перезагрузку поставить на лимит без перезагрузки контролера и пинов но так с первого раза работает
до этого если пользоваться джойстиком работало со второго и последующих
видео снято для телефона , так получилось . извиняйте
вроде все работает . но что то не так
через пару часиков загрузится
//Энкодер на пинах А0, А1. Используется внутренняя подтяжка.
volatile int enc, motor_position;
#define STEP_PIN 2
#define DIR_PIN 5
#define ENABLE_PIN 8
#define limitPin 9
#define button1 4
#define button2 7
void setup(){
Serial.begin(115200);
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);
PCIFR=PCIFR; PCICR=1<<PCIE1; //разрешить прерывание
PCMSK1=1<<PCINT8 | 1<<PCINT9; //выбрать вход на котором сработает прерывание
pinMode(2, OUTPUT);
pinMode(5, OUTPUT);
pinMode(8, OUTPUT);
pinMode(4, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
}
int A = 0;
int T = 1;
ISR(PCINT1_vect, ISR_NOBLOCK){ //ISR(PCINT1_vect) если нет джойстика
static char EncPrev=0; //предыдущее состояние энкодера
static char EncPrevPrev=0; //пред-предыдущее состояние энкодера
char EncCur = 0;
if(!(PINC & (1 << PC0))){EncCur = 1;} //опрос фазы 1 энкодера
if(!(PINC & (1 << PC1))){ EncCur |= 2;} //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{
if(EncPrev == 3 && //если предыдущее состояние 3
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if (EncCur == 2) //если текущее состояние 2,
(enc++, digitalWrite(DIR_PIN , 0), Step());
else //иначе
(enc--, digitalWrite(DIR_PIN , 1), Step());
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}
void Step() {
digitalWrite(ENABLE_PIN , LOW);
digitalWrite(STEP_PIN , HIGH);
delayMicroseconds(T);
digitalWrite(STEP_PIN , LOW);
motor_position++;
}
void loop() {
if (!digitalRead(4)) {delay(5);
digitalWrite(8, LOW);}
if (!digitalRead(7)) {delay(5);
digitalWrite(8, HIGH);}
A = analogRead(A4);
Serial.println(A);
if (A > 520) {
digitalWrite(8, LOW);
T = map(A, 520, 1123, 500, 0);
pinMode(5, OUTPUT);
digitalWrite(5, 1);
Step();
}
if (A < 480) {
digitalWrite(8, LOW);
T = map(A, 480, 0, 500, 0);
pinMode(5, OUTPUT);
digitalWrite(5, 0);
Step();
}
if (A > 480 & A < 520) {
pinMode(5, OUTPUT);
digitalWrite(5, 0);
pinMode(2, OUTPUT);
digitalWrite(2, 0);
}
if (!digitalRead(9)) {
digitalWrite(ENABLE_PIN , LOW);
digitalWrite(DIR_PIN , LOW);
for (int i = 0; i < 200; i++) {
digitalWrite(STEP_PIN , HIGH);
delayMicroseconds(1000);
digitalWrite(STEP_PIN , LOW);
}
delay(2000);
asm volatile("jmp 0x00");
}
}
ты бы не на ютубе размещал всё же
а что еще есть ? телеграмм ,
видео и подача очень плохая , мне даже на ютубе стыдно выкладывать
Рутуб, ВКвидео
Возможно, дело не в энкодере, а в управлении мотором.
Убрал лишнее, на мой взгляд, добавил вывод енкодера в сериал. Проверьте, на сколько значений уходит и возвращается позиция энкодера.
Спойлер
//Энкодер на пинах А0, А1. Используется внутренняя подтяжка.
volatile int enc, motor_position;
#define STEP_PIN 2
#define DIR_PIN 5
#define ENABLE_PIN 8
#define limitPin 9
#define button1 4
#define button2 7
#define checkBtnPeriod 4 //период опроса кнопок,ms
int A = 0;
volatile int T = 1;
uint32_t timeMillis = 0;
void setup(){
Serial.begin(115200);
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);
PCIFR=PCIFR; PCICR=1<<PCIE1; //разрешить прерывание
PCMSK1=1<<PCINT8 | 1<<PCINT9; //выбрать вход на котором сработает прерывание
pinMode(2, OUTPUT);
pinMode(5, OUTPUT);
pinMode(8, OUTPUT);
pinMode(4, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
}
ISR(PCINT1_vect /*, ISR_NOBLOCK*/){ //ISR(PCINT1_vect) если нет джойстика
static char EncPrev=0; //предыдущее состояние энкодера
static char EncPrevPrev=0; //пред-предыдущее состояние энкодера
char EncCur = 0;
if(!(PINC & (1 << PC0))){EncCur = 1;} //опрос фазы 1 энкодера
if(!(PINC & (1 << PC1))){ EncCur |= 2;} //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{
if(EncPrev == 3 && //если предыдущее состояние 3
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if (EncCur == 2) //если текущее состояние 2,
(enc++, digitalWrite(DIR_PIN , 0), Step());
else //иначе
(enc--, digitalWrite(DIR_PIN , 1), Step());
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}
void Step() {
digitalWrite(ENABLE_PIN , LOW);
digitalWrite(STEP_PIN , HIGH);
delayMicroseconds(T);
digitalWrite(STEP_PIN , LOW);
motor_position++;
}
void loop() {
static int16_t enc_m = 0;
if(millis() - timeMillis >= checkBtnPeriod)//опрос кнопок и джойстика
{ //каждые 4мс
timeMillis = millis();
if (!digitalRead(4)) {/*delay(5)*/;
digitalWrite(8, LOW);}
if (!digitalRead(7)) {/*delay(5)*/;
digitalWrite(8, HIGH);}
A = analogRead(A4);
//Serial.println(A);
if(enc != enc_m)
Serial.println(enc);
if (A > 520) {
// digitalWrite(8, LOW);
T = map(A, 520, 1123, 500, 0);
// pinMode(5, OUTPUT);
// digitalWrite(5, 1);
// Step();
}
if (A < 480) {
// digitalWrite(8, LOW);
T = map(A, 480, 0, 500, 0);
// pinMode(5, OUTPUT);
// digitalWrite(5, 0);
// Step();
}
if (A > 480 && A < 520) { //не & а &&
// pinMode(5, OUTPUT);
digitalWrite(5, 0);
// pinMode(2, OUTPUT);
digitalWrite(2, 0);
}
enc_m = enc;
}
if (!digitalRead(9)) {
digitalWrite(ENABLE_PIN , LOW);
digitalWrite(DIR_PIN , LOW);
for (int i = 0; i < 200; i++) {
digitalWrite(STEP_PIN , HIGH);
delayMicroseconds(1000);
digitalWrite(STEP_PIN , LOW);
}
delay(2000);
asm volatile("jmp 0x00");
}
}
P.S. Немного подправил
спасибо , немного погодя попробую ,
я потихоньку разбираюсь. с цифровыми пинами и составил код в пять строк который начал показывать так же точно . но почему то у джойстика стала одна скорость. и лимит редко по разному показывает
но я отстрою .
как с джойстиком разберусь и лимитом сразу выложу
у меня еще оказывается на цифре энкодер работает только нв 2,3 пинах я пробовал на всех
возможно и это была позавчерашняя причина почему я не смог код на цифре запустить от Леонида Ивановича .
некоторые моменты я проверил .
Что бы вернуть джойстик … вернул и некоторые параметры .
#define checkBtnPeriod 1
поставил 1 так квк джойстик на 4 и выше очень медленно крутил мотор
1 мсек . это часто но на точность никак не влияет.
убрал костыль …
“”"
delay(2000);
asm volatile(“jmp 0x00”);
“”"
что бы посмотреть что поменялось .
вроде как поменялось . тес ты с прогоном джойстика и без него сделал раз 50
вроде как теперь с первого раза проход например в 16000 шагов двигателя при 12000 мм мин возвращает мотор на ту же позицию
не теряя сотки
такое было со второго и последующих прогонов . а первый раз он мог потерять и десятку . и даже пару мм . поэтому я и поставил легкий ресет .
джойстик вроде без нареканий работает . но есть условия .
я должен джойстиком довести каретку до концевика и когда она отедет от него в ноль могу запускать прогон туда сюда при этом условии ничего не теряется с первого и последующих раз прогонов .
если я не доведу до концевика . результат бывает разный по патерям .
еще условие . если я руками подведу каретку в любое место и отправлю прогон .то тоже будет потеря мм
далее
я забыл проверить без этого параметра
ISR_NOBLOCK*/
позже проверю
вы спрашивали про потери на энкодере . 16000 шагов _1500 тиков и обратно также 16000_0 возврат и сотые мм возвращаются в своё первоначальное состояния
с точностью нормально
дребезга нет
буду думать как руками двигать или джойстиком не доезжая концевика . ведь в принтере и такая задача может быть когда с середины нужно начать печать.
далее я доделаю позже этот код на цифре ведь он уже готов . осталось проверить на пинах 3 сетки 2-3 ведь я проверял позавчера на 1 сетки а там у меня и мой код не заработал .
хотя на аналоговых вполне меня устраивает только уже не приделаешь потэнцеометр дря регулировки оборотов . в коде нужно прописывать .
далее сделал код на цифровых пинах 2-3
работает хорошо .
точность такая же высокая без пропусков
вопросы с джойстиком и концевиком решил
костыль в виде ресета стоит . без него не получается с первого раза прогнать прогон туда сюда .
попробую ваш код применить у себя
меня и ресет устраивает но бывает он раз из десяти не срабатывает.
еще у меня были проблемы с дребезгом но вроде решил их
и иногда после прогонов начинаешь управлять джойстиком а мотор странные звуки издает как будто в резонансе . вроде тоже решил но не уверен - нужны еще тесты
Вот такой простой код получился .
#define enc_A 2
#define enc_B 3
#define STEP_PIN 4
#define DIR_PIN 7
#define ENABLE_PIN 8
#define limitPin 9
#define button1 6
#define button2 5
volatile long temp, motor_position, enc;
int T = 1;
int A = 0;
void setup (){
Serial.begin (115200);
pinMode(enc_A, INPUT_PULLUP);
pinMode(enc_B, INPUT_PULLUP);
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(ENABLE_PIN , OUTPUT);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
attachInterrupt(0, encPinA, CHANGE);
enc = 0;
}
void encPinA() {
if( enc != temp ){
Serial.println (enc);
temp = enc;
}
if (digitalRead(enc_A) == digitalRead(enc_B))
{if (enc < 0; enc--);
(digitalWrite(DIR_PIN , 1), Step());
} else
{(enc++, digitalWrite(DIR_PIN , 0), Step());}
}
void Step() {
digitalWrite(ENABLE_PIN , LOW);
digitalWrite(STEP_PIN , HIGH);
delayMicroseconds(T);
digitalWrite(STEP_PIN , LOW);
motor_position++;
enc = 0;
}
void loop() {
if (!digitalRead(5)) {delay(5);
digitalWrite(8, LOW);}
if (!digitalRead(6)) {delay(5);
digitalWrite(8, HIGH);}
A = analogRead(A4);
if (A > 520) {
digitalWrite(8, LOW);
T = map(A, 520, 1123, 500, 0);
(digitalWrite(DIR_PIN , 1), Step());
}
if (A < 480) {
digitalWrite(8, LOW);
T = map(A, 480, 0, 500, 0);
(digitalWrite(DIR_PIN , 0), Step());
}
if (A > 480 && A < 520) {
(digitalWrite(DIR_PIN , 0), digitalWrite(STEP_PIN, 0));
}
if (!digitalRead(9)) {
digitalWrite(ENABLE_PIN , HIGH);
delay(150);
digitalWrite(ENABLE_PIN , LOW);
digitalWrite(DIR_PIN , LOW);
for (int i = 0; i < 200; i++) {
digitalWrite(STEP_PIN , HIGH);
delayMicroseconds(1000);
digitalWrite(STEP_PIN , LOW);
}
if (!digitalRead(9))
delay(100);
asm volatile("jmp 0x00");
}
}
PS, код что выше негодный . вчера хорошо работал сегодня плохо считывает .
НЕ ИСПОЛЬЗУЙТЕ ЕГО ДЛЯ ТОЧНЫХ РАБОТ ,
БУДЕТ НОВЫЙ КОД НА ТЕХ ЖЕ ПИНАХ …
код работает хорошо , нет дребезга . точность в сотку зависит от энкодера и деления шага
у меня 1\8 1 тик энкодера 2 сотки
на 1\16 будет 1 к 1 без погрешности не считая прибора
Encpder привязан на pin D2 и D3
joystick на A4
шаговый мотор на
STEP_PIN = 4 , DIR_PIN = 7 , ENABLE_PIN 8
Limit pin = 9
Кнопка удержания шаговика pin 5
Кнопка снятия с удержания шаговика pin 6
const int R360 = 200; мне такое число шагов устраивает что бы при лимите мотор отъезжал на 4 мм .
Далее , буду еще тестить и оптимизировать код . смотреть на его поведения . ведь при желании недочет всегда можно высосать а это мне нравиться .
можно закоментить вывод в принт для быстродействия , но мне всего хватает
Serial.println(enc);
//Энкодер на пинах 2, 3. Используется внутренняя подтяжка.
volatile int enc, motor_position;
#define ENABLE_PIN 8
#define limitPin 9
#define button1 6
#define button2 5
void setup(){
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(ENABLE_PIN , OUTPUT);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
PCIFR=PCIF2; PCICR=1<<PCIE2; //разрешить прерывание
PCMSK2=1<<PCINT18 | 1<<PCINT19; //выбрать вход на котором сработает прерывание
}
const int STEP_PIN = 4;
const int DIR_PIN = 7;
const int move_delay = 3;
const int R360 = 200;
int T = 1;
int A = 0;
ISR(PCINT2_vect){
static char EncPrev=0; //предыдущее состояние энкодера
static char EncPrevPrev=0; //пред-предыдущее состояние энкодера
char EncCur = 0;
if(!(PIND & (1 << PD2))){EncCur = 1;} //опрос фазы 1 энкодера
if(!(PIND & (1 << PD3))){ EncCur |= 2;} //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{ if(EncPrev == 3 && //если предыдущее состояние 3
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == 2) //если текущее состояние 2,
(enc++, digitalWrite(DIR_PIN, 0), Step()); //шаг вверх
else //иначе
(enc--, digitalWrite(DIR_PIN, 1), Step()); //шаг вниз
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}
void Step()
{
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(T);
digitalWrite(STEP_PIN, LOW);
motor_position++;
}
void loop() {
Serial.println(enc);
if (!digitalRead(5)) {delay(5);
digitalWrite(8, LOW);}
if (!digitalRead(6)) {delay(5);
digitalWrite(8, HIGH);}
A = analogRead(A4);
if (A > 520) {
digitalWrite(8, LOW);
T = map(A, 520, 1123, 500, 0);
pinMode(7, OUTPUT);
digitalWrite(7, 1);
Step();
}
if (A < 480) {
digitalWrite(8, LOW);
T = map(A, 480, 0, 500, 0);
pinMode(7, OUTPUT);
digitalWrite(7, 0);
Step();
}
if (A > 480 && A < 520) {
pinMode(7, OUTPUT);
digitalWrite(7, 0);
pinMode(4, OUTPUT);
digitalWrite(4, 0);
}
if (!digitalRead(9)) {
digitalWrite(ENABLE_PIN , HIGH);
delay(150);
digitalWrite(ENABLE_PIN , LOW);
digitalWrite(DIR_PIN , LOW);
for (int i = 0; i < R360; i++) {
digitalWrite(STEP_PIN , HIGH);
delayMicroseconds(1000);
digitalWrite(STEP_PIN , LOW);
}
if (!digitalRead(9))
delay(100);
asm volatile("jmp 0x00");
}
}
Не описание, а поток не сформированных мыслей.
Пока в голове порядок не наведешь, так и будет херня получаться.
ты не одинок в непонимании того, что ТС творит, видимо как и у меня сознание зашорено принципом работы существующих принтеров, в том числе инженерных )))
Добавил в код функцию , уйти на ноль .
нажав на кнопку на Pin 5 каретка самостоятельно выставляется в нулевое положения .
//Энкодер на пинах 2, 3. Используется внутренняя подтяжка.
volatile int enc, motor_position;
#define ENABLE_PIN 8
#define limitPin 9
#define button1 6
#define button2 5
void setup(){
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(ENABLE_PIN , OUTPUT);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
PCIFR=PCIF2; PCICR=1<<PCIE2; //разрешить прерывание
PCMSK2=1<<PCINT18 | 1<<PCINT19; //выбрать вход на котором сработает прерывание
}
const int STEP_PIN = 4;
const int DIR_PIN = 7;
const int R360 = 200; //шагов на полный оборот
int T = 1;
int A = 0;
ISR(PCINT2_vect){
static char EncPrev=0; //предыдущее состояние энкодера
static char EncPrevPrev=0; //пред-предыдущее состояние энкодера
char EncCur = 0;
if(!(PIND & (1 << PD2))){EncCur = 1;} //опрос фазы 1 энкодера
if(!(PIND & (1 << PD3))){ EncCur |= 2;} //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{ if(EncPrev == 3 && //если предыдущее состояние 3
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == 2) //если текущее состояние 2,
(enc++, digitalWrite(DIR_PIN, 0), Step()); //шаг вверх
else //иначе
(enc--, digitalWrite(DIR_PIN, 1), Step()); //шаг вниз
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}
void Step()
{
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(T);
digitalWrite(STEP_PIN, LOW);
motor_position++;
}
void loop() {
Serial.println(enc);
if (!digitalRead(5)) {
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(DIR_PIN, HIGH);
for (int i = 0; (!digitalRead(9)) < 1; i++) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(500);
digitalWrite(STEP_PIN, LOW);
}
}
if (!digitalRead(6)){
digitalWrite(8, HIGH);
}
A = analogRead(A4);
if (A > 520) {
T = map(A, 520, 1123, 500, 0);
digitalWrite(7, 1);
Step();
}
if (A < 480) {
T = map(A, 480, 0, 500, 0);
digitalWrite(7, 0);
Step();
}
if (A > 480 && A < 520) {
digitalWrite(7, 0);
digitalWrite(4, 0);
}
if (!digitalRead(9)) {
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(DIR_PIN, LOW);
for (int i = 0; i < R360; i++) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(800);
digitalWrite(STEP_PIN, LOW);
}
}
if (!digitalRead(9)) {
delay(2000);
asm volatile("jmp 0x00");
}
}
У тебя там “нуля” в принципе нет.
Для выхода в “ноль” нормальные люди используют z-метки энкодера
я знаю что нет . там всего два выхода . програмно можно ноль организовать если этого код потребует .
мне что теперь закоментить ? или под ноль свай написать .
то что есть меня устраивает .
тебе нужен любой в качестве отсчета + один корпус JK триггера и будут тебе метки