есть такой провод . я его не задействовал . думал это земля и защита от наводок .
то что можно с проводом плюс програмно сделать Z выход я не думал , да и зачем ?
обсолютный энкодер все равно не сделаешь , в этом проекте он не нужен
за 0 берем первую метку и погнали .
далее . все 1 с двух пинов считываем и сравниваем . если условия совпали пишем только одну со знаком - или + по условиям и всеэто записывается в память
мотор берет оттуда столько тиков сколько там есть
и если . бывало и такое на 1\4 срывало мотор в резонансе он всеравно выйдя из него приходит на место до последней сотки и это за 6 баксов .
если мне нужно считать обороты или скорость считывания то помимо програмно может так и можно сделать аппаратно , я в этом совсем не силен . одно знаю , нужно будет , научусь сделаю .
а так как код этот написан на портахего счет идет только на увеличения и уменьшения никакой квадратуры там нет .
другие кода у меня по другому опрашивают и там есть квадратура
но в любом случае изначально при старте кода любая метка должна быть выбрана в качестве нулевой и это можно записать как любое число а ноль это удобнее да и бита не занимает в памяти так как он туда не попадает
ты не понял, Z выход даст симметрию по вращению хоть CW хоть CCW тебе же ноль поймать надо
может и не понял , только я опять не понимаю , симметрия это квадратура ? то бишь совмещения сигнала A и B ? а зачем ?
Да я о планшнтниках мало что знаю но принцип работы я понимаю как будет все реализовано .
у меня по оси Y отвечает этот код а также за прочистку головки будет отвечать и мой код и основной принтера . при чистки и других потугах в мотор на моем коде не будет попадать ни одного лишний единицы я изначально придумал два варианта , они оба разные и простые . их я позже реализую
а так я вчера доделал ту часть при которой стол уходит в ноль на одно и тоже расстояния без потери соток
мне кажется тут так все просто а мне говорят нет нуля значит нет симметрии . и я не могу понять как это может влиять на проект ?
Пришлось на концевик поставить сброс таймера по програмному ребуту таймеров .
выставил часть компилятора avr-gcc без него не перезагружались таймеры .
не хватало нормального из ненормальных сбросов счетчика .
не знаю что было бы лучше такой сброс или таймер по прерыванию на сброс сделать было .
последние два кода вечером нормально работали а на следующий день после джойстика самый первый прогон не честно возвращал . не всегда но бывало
видно я за день до этого не отследил все режимы .
вчера переделал . сегодня сного погонял . все хорошо .тики и соточки целые .
конечно охота было совсем без этого обойтись .
попробовать все лимиты джостики запихать в основной цикл и проверить . или поставить таймер на вектор и сброс сделать , может быть позже проверю .
этот код ведет себя хорошо .
//Энкодер на пинах 2, 3. Используется внутренняя подтяжка.
volatile int enc, motor_position;
#include <avr/wdt.h> // Библиотека часть компилятора avr-gcc
#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; //выбрать вход на котором сработает прерывание
}
uint32_t timer = 0;
void(* resetFunc) (void) = 0;
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 reboot() { // функция сторожевого таймера
wdt_disable();
wdt_enable(WDTO_15MS);
while (1) {}
}
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); // pin joystick
if (A > 520) {
T = map(A, 520, 1123, 500, 0);
digitalWrite(7, 1);
Step();
}
if (A < 480) {
T = map(A, 480, 0, 500, 0); // 500, 0); шкала перерасчета
digitalWrite(7, 0);
Step();
}
if (A > 480 && A < 520) { // 480 < Serial.println(A); < 520
digitalWrite(7, 0);
digitalWrite(4, 0);
}
if (!digitalRead(9)) { //pin коцевика
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(DIR_PIN, LOW);
for (int i = 0; i < R360; i++) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(1000); // скорость отьеда от limit
digitalWrite(STEP_PIN, LOW);
}
{ delay(2000);
reboot(); // сброс таймера
}
}
}
Даже не могу себе представить, о чём же это?
Подкупает лишь неподдельный энтузиазм автора)))
Это вообще зачем?
как вычитал это работает только в Arduino Uno
когда я вызываю ресет , это есть в предыдущем коде и этот ресет необычный
asm volatile("jmp адрес вектора порта где идут прерывания на энкодер ");
но в Arduino Uno он работает наполовину даже можно сказать для моего проекта это работает так .
перезагрузил таймеры и энкодер с первого раза начинает считать верно что мне и нужно , а весь код который находится в loop замораживается из за того что … я так думаю что загрузчик не загрузил остальной код или фиг знает , ну и ладно , когда принтер печатает то остальные кнопки и должны быть заблокированы .
но после он так и остается в подвешаном состоянии и мне приходится нажимать ребут кнопкой на плате.
библиотека avr/wdt.h дает возможность докомпилировать то что у меня раньше вылазило с ошибкой .
и эта библ… имеет встроенный watchdog это что и нужно для автоматического ресет в случае зависания .
в этом коде что написан вызвать перезапуск таймера который дает пинка загрузчику выйти из стопора .
далее как у меня в коде .
кнопка 5 отправляет мотор до упора , он упирается в концевик пин 9
отезжает на 4 мм и по истечении 2 сек вызывает функцию reboot(); о котороц вы спрашивали и менее секунды а точнее тысячная доля вводит в ступор контролер перезапускает таймеры на прерывания выводит из ступора и энкодер готов заного считать правильно .
я много раз это проверил все работает без сбоев .
Нет никаких “необычных” ресетов. Ресет - это полный перезапуск МК, когда он начинает выполнение программы с самого начала. При этом обнуляются регистры, глобальные и статические переменные.
P.S. Чтобы победить “хаос”, пишите программу по частям.
Сначала добейтесь , слаженной работы энкодера и мотора,
затем установки 0, и.т.д. Если какой-нибудь шаг пропустить так и будет вылезать непонятная ошибка
плюс еще отрабатывает загрузчик, если он есть…
в двух словах, в чем проблема то, зачем нужны эти перезагрузки контролера?
не спорю . только обычный ресет програмно на этой плате не сделать и от длится 2 сек . а этот сброс длится всего может тысячу тактов что в тысячи раз быстрее .
в двух словах я не умею . я уже несколько раз описывал проблему .
если я джойстиком или кнопками двигаю мотор то включаются таймеры на прерывании … да они там есть … а когда подошла очередь энкодера то он тоже как и все остальное пользуется этими же таймерами и начинает только первый раз считать не правильно . а дальше как то до него это доходит и он исправляется . может происходит сброс таймера по совпадению адреса что скорее всего хотя это вызывается отдельно и я это не прописывал . нужно для этого весь код переписывать .
энкодер с первого раза
Пусть меня поправят, если я не прав, но
Как раз и есть такой “быстрый” ресет без загрузчика
пойду в дискорде зарегюсь , если нужно наглядно что то показать то так проще будет , из меня такой обьяснялка …
Как по мне - лишнее. Нужно именно сформулировать и чётко выразить свою мысль на бумаге - это и будет шаг к решению задачи. Мысль путается, когда сам до конца не понимаешь, что происходит
согласен . я капитан коробля lol … за месяц без базы самостоятельно мало что наловишь .
но я еще всвоей лодке , на берег не собираюсь .
я вообще ничего не понимаю что ТС говорит ни кинематической схемы сего проекта ни программы, если надо знать точное положение головки принтера, то кинематика привода головки должна быть МЕХАНИЧЕСКИ связана с энкодером, у него энкодер крутится от какого-то двигателя, как всё связывается, магия какая-то
Я тоже сначала читал тему и думал, что целиком отупел, раз не могу представить что автор пытается нам втолковать.
надо шар менять, у меня из гранита, не работает видимо по таким проектам, надо заказывать из горного хрусталя
DTG - значит по ткани рисует. Три привода наверное будет. Энкодеры на шаговиках для чёткого позиционирования пера на полотне… Во!, что я понял
без штанов останешься видимо, уж тогда из Агата попробовать, он у нас есть