От нашей бедности и нет возможности купить новый "насос перистальтический"
Хм... тогда либо насос ОЧЕНЬ дорогой, либо вы не представляете себе стоимость программера раз в раздел "ищу исполнителя" сунулись :)
Вы бы расписали поподробнее что это, зачем это с фотками... вам бы и в обычных разделах помогли (наверное :). Пробудили бы интерес. Это для вас "рутина", а для многих это "ух ты... экзотика". Не банальный проект - он привлекает внимание. Правда - там всегда ждут что вы все-таки сами разбираетесь/стараетесь. А вам помогают, а не "за вас делают".
Nikolai54 пишет:
для подачи физ раствора,
Хм.. а зачем вам тогда выводить скорость в RPM? Было-бы юзабеленей в каких-то "милилитрах в минуту" и подобном.
до сих пор у нас в экспериментальной установки работает.
Сын приходит к отцу-программисту:
- Пап, а почему солнце встает на востоке, а садится на западе?
- Что, каждый день?
- Да.
- Без сбоев?
- Ну да.
- Это хорошо, только смотри, ничего там не трогай!
Нам бы скорость поднять, "миллилитрах в минуту" нам не принципиально какие там будут цифры важно стабильно мы бы для себя отработали, хорошо бы шаг уменьшить 1 шаг и при удержании кнопки допустим переходил на шаг например 10 , 1,10 это условно пускай показывает на LCD другие цифры уже не до жиру.
Меняем эти циры. Кроме первой (-1). И общие количество менять нельзя. Можно подкручивать сами цифры. Это задержка между "шагами". Чем меньше задержка - тем быстрее крутимся. Когда вы нажимаете кнопки +/- вы, на самом деле просто переходите по этому массиву вправо/влево. Нажали + - задержка между шагами степера стала 600, нажали еще раз стала 300,150,120 и т.д.
Если нужно "сразу все" увеличить умножить, то меняем циферку в
Timer1.initialize(100);
По идее вот это 100 это, в микросекундах с какой частотой тикает таймер. А 600,300,200 - это сколько раз должен тикнуть таймер прежде чем степпер сделает следующий шаг. То есть сейчас, вы проходите такие скорости
Шаг каждые "600*100 микросекунд", "300*100 микросекунд", "150*100 микросекунд"
Вообщем поиграйтесь с этим цифрами. В массиве и Timer1.initialize();
LCD , при этом, будет показывать все "по старому" :)
Добрый вечер ! У меня вопрос по поведу этого же скетча, есть вариант сделать так чтобы при нажатии на кнопку увеличение скорость , двигатель делал только конкретное количество шагов ?
Добрый вечер ! У меня вопрос по поведу этого же скетча, есть вариант сделать так чтобы при нажатии на кнопку увеличение скорость , двигатель делал только конкретное количество шагов ?
Возможно память меня подводит, но мне смутно помнится, что я, в итоге, "доводил" этот скетч уже напрямую с топик-стартером. С помощью skype. Так что почти наверняка тут не последняя версия скетча. Так что начинать переделки, думаю, нужно с просьбы к Nikolai54 выложить "актуальную версию"
P.S. Это, конечно, если я не перепутал проекты. Но вроде "физиологи" были тут на форуме одни.
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int m=0; //переменная для экранов меню
// количество шагов мотора
#define STEPS 200
// создает класс шагового двигателя и объявляет какими ножками Ардуино
Stepper stepper(STEPS,2,3);
int Step_rev = 0;
int Speed =0;
#define ButtonUp 7
#define ButtonLeft A0
#define ButtonRight A1
#define ButtonMode A2
#define ButtonStop A3
void setup(){
digitalRead(ButtonUp);
digitalRead(ButtonLeft);
digitalRead(ButtonRight);
digitalRead(ButtonMode);
digitalRead(ButtonStop);
lcd.init();
lcd.backlight();
//Выведем на дисплей стартовое сообщение на 2 секунды
lcd.setCursor(0, 0);
lcd.print(" ***** ");
lcd.setCursor(5, 1);
lcd.print("Motor");
delay(3000);
lcd.clear();
//Считаем из постоянной памяти данные
EEPROM_readAnything(0, Step_rev);
EEPROM_readAnything(20, Speed);
}
void loop() {
//Обработка нажатия кнопки меню
if (digitalRead(ButtonLeft) == HIGH)
{
m++;//увеличиваем переменную уровня меню
if (m>2)//если уровень больше 2
{
m=0;// то вернуться к началу
}
delay (300);
lcd.clear();
}
//Обработка нажатия кнопки
if (digitalRead(ButtonMode) == HIGH)
{
// один полный круг вперед
stepper.setSpeed(Speed);
stepper.step(Step_rev);
}
//Обработка нажатия кнопки
if (digitalRead(ButtonUp) == HIGH)
{
// один полный круг назад
stepper.setSpeed(Speed);
stepper.step(-Step_rev);
}
//Обработка нажатия для Kontur - 1 +
if (digitalRead(ButtonRight) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1
{
Step_rev++;//то при нажатии кнопки + увеличиваем переменную Step_rev на единицу
if (Step_rev>800)//если переменная достигла придела в 800 едениц
{
Step_rev=0;//то возвращаем ее к 0
}
delay (50);
lcd.clear();
}
//Обработка нажатия для Kontur - 1 -
if (digitalRead(ButtonStop) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1
{
Step_rev--;//то при нажатии кнопки - уменьшаем переменную Step_rev на единицу
if (Step_rev<0)//если переменная достигла придела в 0 едениц
{
Step_rev=800;//то возвращаем ее к 800
}
delay (50);
lcd.clear();
}
//speed
//Обработка нажатия для Kontur - 1 +
if (digitalRead(ButtonRight) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1
{
Speed++;//то при нажатии кнопки + увеличиваем переменную Speed на единицу
if (Speed>300)//если переменная достигла придела в 300 едениц
{
Speed=0;//то возвращаем ее к 0
}
delay (50);
lcd.clear();
}
//speed
if (digitalRead(ButtonStop) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1
{
Speed--;//то при нажатии кнопки - уменьшаем переменную Speed на единицу
if (Speed<0)//если переменная достигла придела в 0 едениц
{
Speed=300;//то возвращаем ее к 300
}
delay (50);
lcd.clear();
}
//menu
if (m==0){
lcd.setCursor(0, 0);
lcd.print("Steps: ");
lcd.print(Step_rev);
lcd.setCursor(0, 1);
lcd.print("Speed: ");
lcd.print(Speed);
}
else if (m==1)
{
lcd.setCursor(0, 0);
lcd.print(" Steps = ");
lcd.print(Step_rev);
}
else if (m==2)
{
lcd.setCursor(0, 0);
lcd.print(" Speed = ");
lcd.print(Speed);
}
if (digitalRead(ButtonLeft) == HIGH){
EEPROM_writeAnything(0, Step_rev);
EEPROM_writeAnything(2, Speed);
}
}
вот тут надо сделать чтобы одна кнопка постоянно крутила двигатель, а вторая меняла направление
//Обработка нажатия кнопки
if (digitalRead(ButtonMode) == HIGH)
{
// один полный круг вперед
stepper.setSpeed(Speed);
stepper.step(Step_rev);
}
//Обработка нажатия кнопки
if (digitalRead(ButtonUp) == HIGH)
{
// один полный круг назад
stepper.setSpeed(Speed);
stepper.step(-Step_rev);
}
Заведите себе переменную direction. Котая будет иметь значите 1 или -1
Одной кнопкой "крутите",
stepper.step(direction*Step_rev)
А другой кнопкой меняйте, значение direction.
direction*=-1;
Логика на уровне "умножение положительных и отрицательных чисел".
да я это понимаю а вот как правильно это все оформить не знаю ! я извиняюсь может мне и нужно побольше с мелочей поучиться, но мне очень нужно это сделать ! если вас не затруднит можете по подробней пожалуйста !
вот создал переменную вроде как работает а вот как менять значение этой переменной с кнопки не как не пойму?
// Собственно библиотека
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int m=0; //переменная для экранов меню
// количество шагов мотора
#define STEPS 200
// создает класс шагового двигателя и объявляет какими ножками Ардуино
Stepper stepper(STEPS,2,3);
int direct ;
int Step_rev = 0;
int Speed =0;
#define ButtonUp 7
#define ButtonLeft A0
#define ButtonRight A1
#define ButtonMode A2
#define ButtonStop A3
void setup(){
digitalRead(ButtonUp);
digitalRead(ButtonLeft);
digitalRead(ButtonRight);
digitalRead(ButtonMode);
digitalRead(ButtonStop);
lcd.init();
lcd.backlight(); //Выведем на дисплей стартовое сообщение на 2 секунды
lcd.setCursor(0, 0);
lcd.print(" ***** ");
lcd.setCursor(5, 1);
lcd.print("Motor");
delay(3000);
lcd.clear();
//Считаем из постоянной памяти заданную скорость и кол шагов
EEPROM_readAnything(0, Step_rev);
EEPROM_readAnything(20, Speed);
direct = -1;
}
void loop() {
//Обработка нажатия кнопки меню
if (digitalRead(ButtonLeft) == HIGH)
{
m++;//увеличиваем переменную уровня меню
if (m>2)//если уровень больше 2
{
m=0;// то вернуться к началу
}
delay (300);
lcd.clear();
}
//Обработка нажатия кнопки
if (digitalRead(ButtonMode) == HIGH)
{
// один полный круг вперед
stepper.setSpeed(Speed);
stepper.step(direct*Step_rev);
}
//Обработка нажатия кнопки смена направления
if (digitalRead(ButtonUp) == HIGH)
{
}
//Обработка нажатия для Kontur - 1 +
if (digitalRead(ButtonRight) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1
{
Step_rev++;//то при нажатии кнопки + увеличиваем переменную Step_rev на единицу
if (Step_rev>800)//если переменная достигла придела в 800 едениц
{
Step_rev=0;//то возвращаем ее к 0
}
delay (50);
lcd.clear();
}
//Обработка нажатия для Kontur - 1 -
if (digitalRead(ButtonStop) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1
{
Step_rev--;//то при нажатии кнопки - уменьшаем переменную Step_rev на единицу
if (Step_rev<0)//если переменная достигла придела в 0 едениц
{
Step_rev=800;//то возвращаем ее к 800
}
delay (50);
lcd.clear();
}
//speed
//Обработка нажатия для Kontur - 1 +
if (digitalRead(ButtonRight) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1
{
Speed++;//то при нажатии кнопки + увеличиваем переменную Speed на единицу
if (Speed>300)//если переменная достигла придела в 300 едениц
{
Speed=0;//то возвращаем ее к 0
}
delay (50);
lcd.clear();
}
//speed
if (digitalRead(ButtonStop) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1
{
Speed--;//то при нажатии кнопки - уменьшаем переменную Speed на единицу
if (Speed<0)//если переменная достигла придела в 0 едениц
{
Speed=300;//то возвращаем ее к 300
}
delay (50);
lcd.clear();
}
//menu
if (m==0){
lcd.setCursor(0, 0);
lcd.print("Steps: ");
lcd.print(Step_rev);
lcd.setCursor(0, 1);
lcd.print("Speed: ");
lcd.print(Speed);
}
else if (m==1)
{
lcd.setCursor(0, 0);
lcd.print(" Steps = ");
lcd.print(Step_rev);
}
else if (m==2)
{
lcd.setCursor(0, 0);
lcd.print(" Speed = ");
lcd.print(Speed);
}
if (digitalRead(ButtonLeft) == HIGH){
EEPROM_writeAnything(0, Step_rev);
EEPROM_writeAnything(2, Speed);
}
}
Ну вот немного танцев с бубном и кое что вышло, по крайне мере более менее то что нужно ! вот только не могу правильно задержку реализовать чтоб после нажатия кнопки мотор не выполнял больше одного движения хотя бы несколько секунд? и дребизг для кнопок чтот я немогу понять ?
а так вот что у меня получилось буду рад если посмотрите !
// Собственно библиотека
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int m=0; //переменная для экранов меню
// количество шагов мотора
#define STEPS 200
// создает класс шагового двигателя и объявляет какими ножками Ардуино
Stepper stepper(STEPS,2,3);
int regim=1;
int direct = 1;
int Step_rev = 0;
int Speed =0;
long previousMillis = 0;
#define ButtonUp 7
#define ButtonLeft A0
#define ButtonRight A1
#define ButtonMode A2
#define ButtonStop A3
void setup(){
digitalRead(ButtonUp);
digitalRead(ButtonLeft);
digitalRead(ButtonRight);
digitalRead(ButtonMode);
digitalRead(ButtonStop);
lcd.init();
lcd.backlight(); //Выведем на дисплей стартовое сообщение на 2 секунды
lcd.setCursor(0, 0);
lcd.print(" ***** ");
lcd.setCursor(5, 1);
lcd.print("Motor");
delay(3000);
lcd.clear();
//Считаем из постоянной памяти заданную скорость и кол шагов
EEPROM_readAnything(0, Step_rev);
EEPROM_readAnything(20, Speed);
direct = 1;
}
void loop() {
//Обработка нажатия кнопки меню
if (digitalRead(ButtonLeft) == HIGH)
{
m++;//увеличиваем переменную уровня меню
if (m>2)//если уровень больше 2
{
m=0;// то вернуться к началу
}
delay (300);
lcd.clear();
}
//Обработка нажатия кнопки
if (digitalRead(ButtonMode) == HIGH){
{
// один полный круг вперед
stepper.setSpeed(Speed);
stepper.step(direct*Step_rev);
}
delay (1000);
}
//Обработка нажатия кнопки смена направления
if (digitalRead(ButtonUp) == HIGH ){//если кнопка нажата ...
{
regim++;
if(regim>2)//ограничим количество режимов
{
regim=1;//так как мы используем только одну кнопку,
// то переключать режимы будем циклично
}
}
if(regim==1)//первый режим
{
direct=-1;
}
if(regim==2)//второй режим
{
direct=1;
}
delay (500);
}
//Обработка нажатия для Kontur - 1 +
if (digitalRead(ButtonRight) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1
{
Step_rev++;//то при нажатии кнопки + увеличиваем переменную Step_rev на единицу
if (Step_rev>800)//если переменная достигла придела в 800 едениц
{
Step_rev=0;//то возвращаем ее к 0
}
delay (50);
lcd.clear();
}
//Обработка нажатия для Kontur - 1 -
if (digitalRead(ButtonStop) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1
{
Step_rev--;//то при нажатии кнопки - уменьшаем переменную Step_rev на единицу
if (Step_rev<0)//если переменная достигла придела в 0 едениц
{
Step_rev=800;//то возвращаем ее к 800
}
delay (50);
lcd.clear();
}
//speed
//Обработка нажатия для Kontur - 1 +
if (digitalRead(ButtonRight) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1
{
Speed++;//то при нажатии кнопки + увеличиваем переменную Speed на единицу
if (Speed>300)//если переменная достигла придела в 300 едениц
{
Speed=0;//то возвращаем ее к 0
}
delay (50);
lcd.clear();
}
//speed
if (digitalRead(ButtonStop) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1
{
Speed--;//то при нажатии кнопки - уменьшаем переменную Speed на единицу
if (Speed<0)//если переменная достигла придела в 0 едениц
{
Speed=300;//то возвращаем ее к 300
}
delay (50);
lcd.clear();
}
//menu
if (m==0){
lcd.setCursor(0, 0);
lcd.print("Steps: ");
lcd.print(Step_rev);
lcd.setCursor(0, 1);
lcd.print("Speed: ");
lcd.print(Speed);
}
else if (m==1)
{
lcd.setCursor(0, 0);
lcd.print(" Steps = ");
lcd.print(Step_rev);
}
else if (m==2)
{
lcd.setCursor(0, 0);
lcd.print(" Speed = ");
lcd.print(Speed);
}
if (digitalRead(ButtonLeft) == HIGH){
EEPROM_writeAnything(0, Step_rev);
EEPROM_writeAnything(2, Speed);
}
}
А чего "мне смотреть"? Если работает и ВАМ ПОНЯТНО как - то это лучший вариант :)
Хотя - мне не понятно. Зачем вы вводили еще одну переменную regim. Которая используется только для того, что-бы выставлять direction. Почему, в этом if-е сразу не менять саму direction?
switch(direction){
case 1: direction=-1;
break;
case -1:direction=1;
break;
default:
Serial.println("Vignya v direction popala"); // если нет ошибок, эта строчка никогда не выполнится
}
Если уж вы хотите через if менять.
А если, из школы вспомнить что, -1*-1=1 и -1*1=-1, то чередовать 1/-1 можно вообще без if-а. Банальным умножением
direction=-1*direction;
Каждое выполнение этой строки будет менять значение direction с -1 на 1, а 1 на -1
Потом можно вспомнить про унарные операторы (посмотрите в раздел программирование в шапке сайта) и записать это выражение короче
direction*=-1;
Вот мы и пришли, к тому что я вам изначально дал в #60. Которую нужно было только вставить внутрь
if (digitalRead(ButtonUp) == HIGH )
Почему-то вы для первой кнопки вы "взяли и вставили то что я дал", а для второй - пошли "сочинять" :) Вообщем-то это очень даже хорошо :) Только на "сочинениях" и можно чему-то научится.
А еще, рекомендую вам почитать прикрепленную ветку про кнопки. И попробовать переделать все это так, что-бы ловить, действительно именно "нажатие кнопки", не срабатывать лишний раз при ее "удержании". Избавится от delay().
Возможно память меня подводит, но мне смутно помнится, что я, в итоге, "доводил" этот скетч уже напрямую с топик-стартером. С помощью skype. Так что почти наверняка тут не последняя версия скетча. Так что начинать переделки, думаю, нужно с просьбы к Nikolai54 выложить "актуальную версию"
P.S. Это, конечно, если я не перепутал проекты. Но вроде "физиологи" были тут на форуме одни.
Да делали для нашей лабы, за что Вам большое спасибо, единстевенно что не доделали отклчения двигателя, постоянно под напряжением, греется. А так все ок еще раз спасибо Вам Алексей.
// by alxarduino@gmail.com aka leshak (arduino.ru)
#include <LiquidCrystal.h>
#include <TimerOne.h>
#include <EEPROM.h> // для сохранения значение в энергонезависимую память
/******************* Конфигурация ***************************/
// параметры "скорости"
#define START_SPEED 20 // изначальная скорость "в тиках таймера между шагами"
#define MAX_STEP_DELAY 20000 // максимальная задержка между шагами (самая медленная возможная скорость)
#define MIN_STEP_DELAY 9 // минимальная задержка между шагами (самая быстрая возвожная скорость)
#define LONG_STEP_MULT 10 // при длинных нажатиях Up/Down скорость будет менятся на SPEP*LONG_STEP_MULT
// параметры "шага изменения скорости" aka "делитель"
#define START_TIKS_STEP 20 // изначальные "шаг изменения" скорости кнопками UP/DOWN, сам шаг меняется кнопками RIGH/LEFT
#define TICKS_STEP_STEP 1 // скорость изменения скорости изменения кнопками RIGH/LEFT
#define TICKS_STEP_STEP_LONG 10 // скорость изменения скорости изменения кнопками RIGH/LEFT при "долгом нажатии"
#define MIN_STEP 1 // минимально возможный шаг
#define MAX_STEP 1000 // максимально возможный шаг
// debounce time (milliseconds)
#define DEBOUNCE_TIME 500 // "антидребезг". сколько времени не реагировать на кнопки после очередного нажатия
#define LONG_PRESS 1000 // если кнопка нажата дольше этого времени (миллисекунды), то нажатие считается "длинным нажатием"
#define DIRECTION true // направление вращения
// Отладочная конфигурация
#define DBG Serial // закоментируйте эту строчку если работы с Serial не нужна
#ifdef DBG
#define SERIAL_SPEED 57600 // скорость ком-порта. в него выводим лог
#endif
/******************** Подключение *****************************************/
// PINs for Pololu controller
#define PIN_STEP 2
#define PIN_DIR 3
// пины куда экран подключен
#define LCD_PINS 8, 9, 4, 5, 6, 7
/********************Энерго независимая конфиграция ********/
#define LOAD_STATE_ON_START true // если true - начальные значения ticks/tickStep загрузятся из EEPROM, если false - будут использованы START_SPEED и START_TIKS_STEP из конфигурации выше
#define SAVE_INTERVAL 5000UL // время в течении которого tiks/tickStep не должны меняться что-бы "сохранится" в EEPROM
#define ADDR_TICKS 0 // начальный адрес, куда будем сохранять переменную tiks
#define ADDR_TICKSTEP (ADDR_TICKS+sizeof(ticks)) // адрес куда будет сохранятся ticks, не менять. вычисляется сам
/************************************************************/
// Глобальные переменные
volatile int ticks=START_SPEED; // сколько нужно сделать "тиков" таймера между шагами
static int tickStep=START_TIKS_STEP; // на сколько меняется скоростьи при каждом нажатии кнопок UP/DOWN
volatile bool isRun=false; // запущено или нет
bool saveRequired=false; // требуется ли сохранение параметров в EEPROM
bool isLongPress=false; // кнопку "удерживает" дольше чем LONG_PRESS времени
// buttons code
typedef enum buttons_codes{
btnNONE=0,
btnUP, //1
btnDOWN, //2
btnLEFT, //3
btnRIGHT, //4
btnSELECT, //5
btnDirectSet // физически такой кнопки нет, используется только "псевдо-кнопками" из сериал что-бы сразу уставноить скорость командой вида =500;
// всегда должна быть "последней", используется как "признак окончания" списка кодов
};
typedef void (*CommandHandler)(); // тип "обрабочик команды", функция вида void someFunction();
CommandHandler command_handlers[btnDirectSet]={ // таблица обработчиков коммнад, обработчики должны быть в том же порядке что и buttons_codes
increase_speed, // UP
decrease_speed, //DOWN
decrease_step, // LEFT
increase_step, // RIGHT
start_stop, // SELECT
set_speed // btnDirectSet
};
// global variables
LiquidCrystal lcd(LCD_PINS);
void setup() {
#ifdef DBG
DBG.begin(SERIAL_SPEED);//
#endif
if(LOAD_STATE_ON_START)loadState(); // если нужно загружаем скорость/шаг из энергонезависимой памяти
// init the timer1, interrupt every 0.1ms
Timer1.initialize(100);
Timer1.attachInterrupt(timerIsr);
// init LCD and custom symbol
lcd.begin(16, 2);
lcd.setCursor(0,0);
// pins direction
pinMode(PIN_STEP, OUTPUT);
pinMode(PIN_DIR, OUTPUT);
// initial values
digitalWrite(PIN_DIR, DIRECTION);
showState(); // показываем текущие состояние на LCD/Serial
}
void loop() {
int button=getButtonCode(); // получаем код кнопки (с защитой от анти-дребезга, с настоящих кнопок и "псевдо из serial")
if(button) { //если кнопка нажата -
command_handlers[button-1](); // вызываем соотвествующий обработчик по таблице command_handlers[]
showState(); // показываем текущие состояние на LCD/Serial
}
monitorAndSaveState(); // следим за текущей скорость/шагом, если они меняются - сохраняем их в EEPROM
}
// *********************** Обработчики прерываний *****************************/
// timer1 interrupt function
// собственно функция которая делает "шаги" степером
void timerIsr() {
if(!isRun)return; // не запущен, не нужно ничего делать
static volatile int tick_count=0; // сколько раз тикнул таймер от предыдущего степе
tick_count++;
if(tick_count >= ticks) { // пора делать шаг
// make a step
digitalWrite(PIN_STEP, HIGH);
digitalWrite(PIN_STEP, LOW);
tick_count = 0; // запустили счетчик заново
}
}
// **************************************** Обработчики комманд *****************************
// increase speed if it's below the max (70)
void increase_speed() {
ticks=constrain(ticks-tickStep*(isLongPress?LONG_STEP_MULT:1),MIN_STEP_DELAY,MAX_STEP_DELAY); // уменьшая задержку - увеличиваем скорость
}
// decrease speed if it's above the min (0)
void decrease_speed() {
ticks=constrain(ticks+tickStep*(isLongPress?LONG_STEP_MULT:1),MIN_STEP_DELAY,MAX_STEP_DELAY); // увеличивая задержку - уменьшаем скорость
}
void increase_step(){ // увеличивает "шаг изменения" aka "делитель"
tickStep=constrain(tickStep+(isLongPress?TICKS_STEP_STEP_LONG:TICKS_STEP_STEP),MIN_STEP,MAX_STEP);
}
void decrease_step(){ // уменьшает "шаг изменения"
tickStep=constrain(tickStep-(isLongPress?TICKS_STEP_STEP_LONG:TICKS_STEP_STEP),MIN_STEP,MAX_STEP);
}
// emergency stop: speed 0
void start_stop() {
isRun=!isRun;
}
void set_speed(){
#ifdef DBG
unsigned int newSpeed=DBG.parseInt();
Serial.print("New Speed=");
Serial.println(newSpeed);
ticks=constrain(newSpeed,MIN_STEP_DELAY,MAX_STEP_DELAY);
#endif
}
// **************************************** /Обработчики комманд *****************************
// ********************** Вывод текущиего состояния **************************************/
// отображает текущие состояние (на экран, в Serial и т.п.)
void showState(){
updateLCD();
#ifdef DBG
updateToSerial();
#endif
}
// update LCD
void updateLCD() {
// print first line:
lcd.setCursor(0,0);
lcd.print("SD:"); // SD - Step Delay
lcd.print(ticks);
lcd.print(" "); // затираем финальные нули от больших чисел, лень высчитывать точное количетсво пробелов
lcd.setCursor(14,0);
if(isRun)lcd.print(" "); // запущенно
else lcd.print("P");
lcd.print(saveRequired?"*":" "); // показываем нужно ли сохранение.
// Вторая строка
// скорость изменения
lcd.setCursor(0,1);
lcd.print("Step:");
lcd.print(tickStep);
lcd.print(" "); // затираем финальные нули от больших чисел, лень высчитывать точное количетсво пробелов
}
#ifdef DBG
void updateToSerial(){
// Выводим время
Serial.print("["); Serial.print(millis());Serial.print("] ");
Serial.print("isRun=");Serial.print(isRun);
Serial.print(", ticks=");Serial.print(ticks);
Serial.print(", step=");Serial.print(tickStep);
Serial.print(", saveRequired=");Serial.print(saveRequired);
Serial.println();
}
#endif
/*********************************************************************************************/
/************************ Обработка кнопок ************************************************/
// read buttons connected to a single analog pin
int read_buttons() {
int adc_key_in = analogRead(0);
if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE;
}
// объдиняем в себе read_serial_buttons() и read_debounces_buttons() от кого пришел "код кнопки", от того и возвращает
int getButtonCode(){
int button=read_debounces_buttons();// вначале пытаемся прочитать настоящие кнопки
#ifdef DBG
if(!button)button=read_serial_buttons(); // если настоящую не нажали, пытаемся прочитать "псевдо-кнопку"
#endif
return button;
}
// то же самое что и read_buttons() только с защитой от дребезга
int read_debounces_buttons(){
int buttonResult; // что вернет функция
static int prevButton=btnNONE; // состояние кнопки при прошлом вызове
static boolean debounce=false;
static unsigned long previous_time;
static unsigned long lastButtonStateChanged;// когда последний раз менялось настоящие состояние кнопки, используется для определения "длинных" нажатий
int realButtonState=read_buttons();
// check if debounce active
if(debounce) {
buttonResult = btnNONE;
if(millis() - previous_time > DEBOUNCE_TIME) debounce = false;
} else buttonResult = realButtonState; // вернем настоящие состояние кнопки
// if a button is pressed, start debounce time
if(buttonResult) {
previous_time = millis();
debounce = true;
}
if(prevButton!=realButtonState){
lastButtonStateChanged=millis();
}
isLongPress=(millis()-lastButtonStateChanged>=LONG_PRESS); // выставили глобальную переменную указывающую это "длинное нажатие" или нет
prevButton=realButtonState;// сохранили настоящие состояние кнопки
return buttonResult;
}
// аналог read_buttons() только "кнопки" читает и Serial
int read_serial_buttons(){
static char cmdChars[btnDirectSet]={'u','d','l','r','s','='}; // Up/Down/Left/Righ/Select/=500;
if(Serial.available()){
char ch=Serial.read(); // читаем пришедший символ
// ищем его в списке команд и его индекс возвращаем в качестве "кода кнопки"
for(byte i=0;i<btnDirectSet;i++)if(cmdChars[i]==ch)return i+1;
}
return btnNONE; // ничего не нашли
}
/******************** Сохранение/запись ticks и tickStep в энергонезависимую память ***********************************************/
// три "помогалки" для чтения/записи int-та в eeprom
void saveInt(int addr, int* value){
byte* p=(byte*)value;
for(byte i=0;i<sizeof(int);i++)EEPROM.write(addr+i,*p++);
}
// То же самое что saveInt, только предварительно делает чтение и записывает только если значение действительно отличается. для экономии циклов записи.
void saveIntSmart(int addr,int* value){
int currentValue=loadInt(addr);
if(currentValue!=*value)saveInt(addr,value);
}
int loadInt(int addr){
int result;
byte* p=(byte*)&result;
for (byte i = 0; i < sizeof(int); i++)*p++ = EEPROM.read(addr+i);
return result;
}
// сохраняет текущие ticks и tickStep в eeprom
void saveState(){
saveIntSmart(ADDR_TICKS,(int *)&ticks);
saveIntSmart(ADDR_TICKSTEP,&tickStep);
}
void loadState(){
ticks=loadInt(ADDR_TICKS);
tickStep=loadInt(ADDR_TICKSTEP);
}
// следит за изменением переменных ticks и tickStep
// если они поменялиь и сохраняют свое значение дольше SAVE_INTERVAL
// записывает их в eeprom
void monitorAndSaveState(){
static int prevTicks=ticks; // инициализируем, что-бы при первом вызове не включался режим сохранения
static int prevTickStep=tickStep;
static unsigned long lastChangeTime=0; // когда состояние менялось последний раз
if(prevTicks!=ticks || prevTickStep!=tickStep){
saveRequired=true; // выставляем флаг что требуется сохранение
lastChangeTime=millis(); // и запомнили когда произошло изменение
showState();
}
if(saveRequired && ( (millis()-lastChangeTime)>SAVE_INTERVAL)){ // если сохранение требуется и прошло достаточно времени
saveState();// сохраняем
saveRequired=false;// и снимаем флаг "нужно сохранение"
showState(); // показываем текущие состояние на LCD/Serial
}
// запоминаем на следующий проход
prevTicks=ticks;
prevTickStep=tickStep;
}
От нашей бедности и нет возможности купить новый "насос перистальтический"
Хм... тогда либо насос ОЧЕНЬ дорогой, либо вы не представляете себе стоимость программера раз в раздел "ищу исполнителя" сунулись :)
Вы бы расписали поподробнее что это, зачем это с фотками... вам бы и в обычных разделах помогли (наверное :). Пробудили бы интерес. Это для вас "рутина", а для многих это "ух ты... экзотика". Не банальный проект - он привлекает внимание. Правда - там всегда ждут что вы все-таки сами разбираетесь/стараетесь. А вам помогают, а не "за вас делают".
для подачи физ раствора,
Хм.. а зачем вам тогда выводить скорость в RPM? Было-бы юзабеленей в каких-то "милилитрах в минуту" и подобном.
В идеале - нужен еще что-то такое Расходомер жидкости | Аппаратная платформа Arduino
И... если это где-то в медицине используется, на живых людях... то всяких защит нужно побольше натыкать. Защиту от зависаний и т.п.
Хотя конечно, реальный прибор, не прототип.... на ардуине и проводках... в прочем, по сравнению с советской техникой - возможно и это лучше будет.
до сих пор у нас в экспериментальной установки работает.
Сын приходит к отцу-программисту:
- Пап, а почему солнце встает на востоке, а садится на западе?
- Что, каждый день?
- Да.
- Без сбоев?
- Ну да.
- Это хорошо, только смотри, ничего там не трогай!
Нам бы скорость поднять, "миллилитрах в минуту" нам не принципиально какие там будут цифры важно стабильно мы бы для себя отработали, хорошо бы шаг уменьшить 1 шаг и при удержании кнопки допустим переходил на шаг например 10 , 1,10 это условно пускай показывает на LCD другие цифры уже не до жиру.
LCD другие цифры уже не до жиру.
Ну, если ваc на LCD устраивает цифра "в попугаях" (кстати я не уверен, что он сейчас там "настоящую скорость показывает"), то тут все просто:
Массив:
const int speed_ticks[] = {-1, 600, 300, 200, 150, 120, 100, 86, 75, 67, 60, 55, 50, 46, 43};Меняем эти циры. Кроме первой (-1). И общие количество менять нельзя. Можно подкручивать сами цифры. Это задержка между "шагами". Чем меньше задержка - тем быстрее крутимся. Когда вы нажимаете кнопки +/- вы, на самом деле просто переходите по этому массиву вправо/влево. Нажали + - задержка между шагами степера стала 600, нажали еще раз стала 300,150,120 и т.д.
Если нужно "сразу все" увеличить умножить, то меняем циферку в
По идее вот это 100 это, в микросекундах с какой частотой тикает таймер. А 600,300,200 - это сколько раз должен тикнуть таймер прежде чем степпер сделает следующий шаг. То есть сейчас, вы проходите такие скорости
Шаг каждые "600*100 микросекунд", "300*100 микросекунд", "150*100 микросекунд"
Вообщем поиграйтесь с этим цифрами. В массиве и Timer1.initialize();
LCD , при этом, будет показывать все "по старому" :)
Добрый вечер ! У меня вопрос по поведу этого же скетча, есть вариант сделать так чтобы при нажатии на кнопку увеличение скорость , двигатель делал только конкретное количество шагов ?
Добрый вечер ! У меня вопрос по поведу этого же скетча, есть вариант сделать так чтобы при нажатии на кнопку увеличение скорость , двигатель делал только конкретное количество шагов ?
Проще сделать отдельную кнопку
Это было бы еще лучше ! ток как это сделать?
Возможно память меня подводит, но мне смутно помнится, что я, в итоге, "доводил" этот скетч уже напрямую с топик-стартером. С помощью skype. Так что почти наверняка тут не последняя версия скетча. Так что начинать переделки, думаю, нужно с просьбы к Nikolai54 выложить "актуальную версию"
P.S. Это, конечно, если я не перепутал проекты. Но вроде "физиологи" были тут на форуме одни.
вот есть еще скатч может в нем проще поправить
вот видео работы скетча http://www.youtube.com/watch?feature=player_embedded&v=zYI5G8f9034
#include <EEPROM.h> #include "EEPROMAnything.h" #include <Stepper.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,20,4); int m=0; //переменная для экранов меню // количество шагов мотора #define STEPS 200 // создает класс шагового двигателя и объявляет какими ножками Ардуино Stepper stepper(STEPS,2,3); int Step_rev = 0; int Speed =0; #define ButtonUp 7 #define ButtonLeft A0 #define ButtonRight A1 #define ButtonMode A2 #define ButtonStop A3 void setup(){ digitalRead(ButtonUp); digitalRead(ButtonLeft); digitalRead(ButtonRight); digitalRead(ButtonMode); digitalRead(ButtonStop); lcd.init(); lcd.backlight(); //Выведем на дисплей стартовое сообщение на 2 секунды lcd.setCursor(0, 0); lcd.print(" ***** "); lcd.setCursor(5, 1); lcd.print("Motor"); delay(3000); lcd.clear(); //Считаем из постоянной памяти данные EEPROM_readAnything(0, Step_rev); EEPROM_readAnything(20, Speed); } void loop() { //Обработка нажатия кнопки меню if (digitalRead(ButtonLeft) == HIGH) { m++;//увеличиваем переменную уровня меню if (m>2)//если уровень больше 2 { m=0;// то вернуться к началу } delay (300); lcd.clear(); } //Обработка нажатия кнопки if (digitalRead(ButtonMode) == HIGH) { // один полный круг вперед stepper.setSpeed(Speed); stepper.step(Step_rev); } //Обработка нажатия кнопки if (digitalRead(ButtonUp) == HIGH) { // один полный круг назад stepper.setSpeed(Speed); stepper.step(-Step_rev); } //Обработка нажатия для Kontur - 1 + if (digitalRead(ButtonRight) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1 { Step_rev++;//то при нажатии кнопки + увеличиваем переменную Step_rev на единицу if (Step_rev>800)//если переменная достигла придела в 800 едениц { Step_rev=0;//то возвращаем ее к 0 } delay (50); lcd.clear(); } //Обработка нажатия для Kontur - 1 - if (digitalRead(ButtonStop) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1 { Step_rev--;//то при нажатии кнопки - уменьшаем переменную Step_rev на единицу if (Step_rev<0)//если переменная достигла придела в 0 едениц { Step_rev=800;//то возвращаем ее к 800 } delay (50); lcd.clear(); } //speed //Обработка нажатия для Kontur - 1 + if (digitalRead(ButtonRight) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1 { Speed++;//то при нажатии кнопки + увеличиваем переменную Speed на единицу if (Speed>300)//если переменная достигла придела в 300 едениц { Speed=0;//то возвращаем ее к 0 } delay (50); lcd.clear(); } //speed if (digitalRead(ButtonStop) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1 { Speed--;//то при нажатии кнопки - уменьшаем переменную Speed на единицу if (Speed<0)//если переменная достигла придела в 0 едениц { Speed=300;//то возвращаем ее к 300 } delay (50); lcd.clear(); } //menu if (m==0){ lcd.setCursor(0, 0); lcd.print("Steps: "); lcd.print(Step_rev); lcd.setCursor(0, 1); lcd.print("Speed: "); lcd.print(Speed); } else if (m==1) { lcd.setCursor(0, 0); lcd.print(" Steps = "); lcd.print(Step_rev); } else if (m==2) { lcd.setCursor(0, 0); lcd.print(" Speed = "); lcd.print(Speed); } if (digitalRead(ButtonLeft) == HIGH){ EEPROM_writeAnything(0, Step_rev); EEPROM_writeAnything(2, Speed); } }вот тут надо сделать чтобы одна кнопка постоянно крутила двигатель, а вторая меняла направление
//Обработка нажатия кнопки if (digitalRead(ButtonMode) == HIGH) { // один полный круг вперед stepper.setSpeed(Speed); stepper.step(Step_rev); } //Обработка нажатия кнопки if (digitalRead(ButtonUp) == HIGH) { // один полный круг назад stepper.setSpeed(Speed); stepper.step(-Step_rev); }Ну, дык а в чем проблема?
Заведите себе переменную direction. Котая будет иметь значите 1 или -1
Одной кнопкой "крутите",
А другой кнопкой меняйте, значение direction.
Логика на уровне "умножение положительных и отрицательных чисел".
Ну, дык а в чем проблема?
Заведите себе переменную direction. Котая будет иметь значите 1 или -1
Одной кнопкой "крутите",
А другой кнопкой меняйте, значение direction.
Логика на уровне "умножение положительных и отрицательных чисел".
да я это понимаю а вот как правильно это все оформить не знаю ! я извиняюсь может мне и нужно побольше с мелочей поучиться, но мне очень нужно это сделать ! если вас не затруднит можете по подробней пожалуйста !
вот создал переменную вроде как работает а вот как менять значение этой переменной с кнопки не как не пойму?
// Собственно библиотека #include <EEPROM.h> #include "EEPROMAnything.h" #include <Stepper.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,20,4); int m=0; //переменная для экранов меню // количество шагов мотора #define STEPS 200 // создает класс шагового двигателя и объявляет какими ножками Ардуино Stepper stepper(STEPS,2,3); int direct ; int Step_rev = 0; int Speed =0; #define ButtonUp 7 #define ButtonLeft A0 #define ButtonRight A1 #define ButtonMode A2 #define ButtonStop A3 void setup(){ digitalRead(ButtonUp); digitalRead(ButtonLeft); digitalRead(ButtonRight); digitalRead(ButtonMode); digitalRead(ButtonStop); lcd.init(); lcd.backlight(); //Выведем на дисплей стартовое сообщение на 2 секунды lcd.setCursor(0, 0); lcd.print(" ***** "); lcd.setCursor(5, 1); lcd.print("Motor"); delay(3000); lcd.clear(); //Считаем из постоянной памяти заданную скорость и кол шагов EEPROM_readAnything(0, Step_rev); EEPROM_readAnything(20, Speed); direct = -1; } void loop() { //Обработка нажатия кнопки меню if (digitalRead(ButtonLeft) == HIGH) { m++;//увеличиваем переменную уровня меню if (m>2)//если уровень больше 2 { m=0;// то вернуться к началу } delay (300); lcd.clear(); } //Обработка нажатия кнопки if (digitalRead(ButtonMode) == HIGH) { // один полный круг вперед stepper.setSpeed(Speed); stepper.step(direct*Step_rev); } //Обработка нажатия кнопки смена направления if (digitalRead(ButtonUp) == HIGH) { } //Обработка нажатия для Kontur - 1 + if (digitalRead(ButtonRight) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1 { Step_rev++;//то при нажатии кнопки + увеличиваем переменную Step_rev на единицу if (Step_rev>800)//если переменная достигла придела в 800 едениц { Step_rev=0;//то возвращаем ее к 0 } delay (50); lcd.clear(); } //Обработка нажатия для Kontur - 1 - if (digitalRead(ButtonStop) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1 { Step_rev--;//то при нажатии кнопки - уменьшаем переменную Step_rev на единицу if (Step_rev<0)//если переменная достигла придела в 0 едениц { Step_rev=800;//то возвращаем ее к 800 } delay (50); lcd.clear(); } //speed //Обработка нажатия для Kontur - 1 + if (digitalRead(ButtonRight) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1 { Speed++;//то при нажатии кнопки + увеличиваем переменную Speed на единицу if (Speed>300)//если переменная достигла придела в 300 едениц { Speed=0;//то возвращаем ее к 0 } delay (50); lcd.clear(); } //speed if (digitalRead(ButtonStop) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1 { Speed--;//то при нажатии кнопки - уменьшаем переменную Speed на единицу if (Speed<0)//если переменная достигла придела в 0 едениц { Speed=300;//то возвращаем ее к 300 } delay (50); lcd.clear(); } //menu if (m==0){ lcd.setCursor(0, 0); lcd.print("Steps: "); lcd.print(Step_rev); lcd.setCursor(0, 1); lcd.print("Speed: "); lcd.print(Speed); } else if (m==1) { lcd.setCursor(0, 0); lcd.print(" Steps = "); lcd.print(Step_rev); } else if (m==2) { lcd.setCursor(0, 0); lcd.print(" Speed = "); lcd.print(Speed); } if (digitalRead(ButtonLeft) == HIGH){ EEPROM_writeAnything(0, Step_rev); EEPROM_writeAnything(2, Speed); } }Ну вот немного танцев с бубном и кое что вышло, по крайне мере более менее то что нужно ! вот только не могу правильно задержку реализовать чтоб после нажатия кнопки мотор не выполнял больше одного движения хотя бы несколько секунд? и дребизг для кнопок чтот я немогу понять ?
а так вот что у меня получилось буду рад если посмотрите !
// Собственно библиотека #include <EEPROM.h> #include "EEPROMAnything.h" #include <Stepper.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,20,4); int m=0; //переменная для экранов меню // количество шагов мотора #define STEPS 200 // создает класс шагового двигателя и объявляет какими ножками Ардуино Stepper stepper(STEPS,2,3); int regim=1; int direct = 1; int Step_rev = 0; int Speed =0; long previousMillis = 0; #define ButtonUp 7 #define ButtonLeft A0 #define ButtonRight A1 #define ButtonMode A2 #define ButtonStop A3 void setup(){ digitalRead(ButtonUp); digitalRead(ButtonLeft); digitalRead(ButtonRight); digitalRead(ButtonMode); digitalRead(ButtonStop); lcd.init(); lcd.backlight(); //Выведем на дисплей стартовое сообщение на 2 секунды lcd.setCursor(0, 0); lcd.print(" ***** "); lcd.setCursor(5, 1); lcd.print("Motor"); delay(3000); lcd.clear(); //Считаем из постоянной памяти заданную скорость и кол шагов EEPROM_readAnything(0, Step_rev); EEPROM_readAnything(20, Speed); direct = 1; } void loop() { //Обработка нажатия кнопки меню if (digitalRead(ButtonLeft) == HIGH) { m++;//увеличиваем переменную уровня меню if (m>2)//если уровень больше 2 { m=0;// то вернуться к началу } delay (300); lcd.clear(); } //Обработка нажатия кнопки if (digitalRead(ButtonMode) == HIGH){ { // один полный круг вперед stepper.setSpeed(Speed); stepper.step(direct*Step_rev); } delay (1000); } //Обработка нажатия кнопки смена направления if (digitalRead(ButtonUp) == HIGH ){//если кнопка нажата ... { regim++; if(regim>2)//ограничим количество режимов { regim=1;//так как мы используем только одну кнопку, // то переключать режимы будем циклично } } if(regim==1)//первый режим { direct=-1; } if(regim==2)//второй режим { direct=1; } delay (500); } //Обработка нажатия для Kontur - 1 + if (digitalRead(ButtonRight) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1 { Step_rev++;//то при нажатии кнопки + увеличиваем переменную Step_rev на единицу if (Step_rev>800)//если переменная достигла придела в 800 едениц { Step_rev=0;//то возвращаем ее к 0 } delay (50); lcd.clear(); } //Обработка нажатия для Kontur - 1 - if (digitalRead(ButtonStop) == HIGH && m==1)//если находимся на экране с переменной Kontur - 1 { Step_rev--;//то при нажатии кнопки - уменьшаем переменную Step_rev на единицу if (Step_rev<0)//если переменная достигла придела в 0 едениц { Step_rev=800;//то возвращаем ее к 800 } delay (50); lcd.clear(); } //speed //Обработка нажатия для Kontur - 1 + if (digitalRead(ButtonRight) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1 { Speed++;//то при нажатии кнопки + увеличиваем переменную Speed на единицу if (Speed>300)//если переменная достигла придела в 300 едениц { Speed=0;//то возвращаем ее к 0 } delay (50); lcd.clear(); } //speed if (digitalRead(ButtonStop) == HIGH && m==2)//если находимся на экране с переменной Kontur - 1 { Speed--;//то при нажатии кнопки - уменьшаем переменную Speed на единицу if (Speed<0)//если переменная достигла придела в 0 едениц { Speed=300;//то возвращаем ее к 300 } delay (50); lcd.clear(); } //menu if (m==0){ lcd.setCursor(0, 0); lcd.print("Steps: "); lcd.print(Step_rev); lcd.setCursor(0, 1); lcd.print("Speed: "); lcd.print(Speed); } else if (m==1) { lcd.setCursor(0, 0); lcd.print(" Steps = "); lcd.print(Step_rev); } else if (m==2) { lcd.setCursor(0, 0); lcd.print(" Speed = "); lcd.print(Speed); } if (digitalRead(ButtonLeft) == HIGH){ EEPROM_writeAnything(0, Step_rev); EEPROM_writeAnything(2, Speed); } }А чего "мне смотреть"? Если работает и ВАМ ПОНЯТНО как - то это лучший вариант :)
Хотя - мне не понятно. Зачем вы вводили еще одну переменную regim. Которая используется только для того, что-бы выставлять direction. Почему, в этом if-е сразу не менять саму direction?
if(direction==1){ direction=-1; } else { // значит direction==-1 direction=1; }Или через switch
switch(direction){ case 1: direction=-1; break; case -1:direction=1; break; default: Serial.println("Vignya v direction popala"); // если нет ошибок, эта строчка никогда не выполнится }Если уж вы хотите через if менять.
А если, из школы вспомнить что, -1*-1=1 и -1*1=-1, то чередовать 1/-1 можно вообще без if-а. Банальным умножением
Каждое выполнение этой строки будет менять значение direction с -1 на 1, а 1 на -1
Потом можно вспомнить про унарные операторы (посмотрите в раздел программирование в шапке сайта) и записать это выражение короче
Вот мы и пришли, к тому что я вам изначально дал в #60. Которую нужно было только вставить внутрь
Почему-то вы для первой кнопки вы "взяли и вставили то что я дал", а для второй - пошли "сочинять" :) Вообщем-то это очень даже хорошо :) Только на "сочинениях" и можно чему-то научится.
А еще, рекомендую вам почитать прикрепленную ветку про кнопки. И попробовать переделать все это так, что-бы ловить, действительно именно "нажатие кнопки", не срабатывать лишний раз при ее "удержании". Избавится от delay().
Возможно память меня подводит, но мне смутно помнится, что я, в итоге, "доводил" этот скетч уже напрямую с топик-стартером. С помощью skype. Так что почти наверняка тут не последняя версия скетча. Так что начинать переделки, думаю, нужно с просьбы к Nikolai54 выложить "актуальную версию"
P.S. Это, конечно, если я не перепутал проекты. Но вроде "физиологи" были тут на форуме одни.
Да делали для нашей лабы, за что Вам большое спасибо, единстевенно что не доделали отклчения двигателя, постоянно под напряжением, греется. А так все ок еще раз спасибо Вам Алексей.
Вот скетч
Тема уже не актуальна?