Имеем Uno, LCD keypad shield, внешний драйвер и шаговый мотор. Делаю дозатор. Всё работает кроме одного. Если выставить до 100 мл то ардуино правильно расчитывает количество оборотов, если больше то логика вся сбивается и мне обсолютсно не понятно почему. Допустим за один оборот насос прокачивает 5мл. то есть что бы накачать 100мл нужно сделать 20 оборотов, ардуино прекрасно отрабатывает. А если выставить 200мл, то ардуино делает четверть оборота, а если выставить 300мл, то 18 оборотов. Всю голову сломал. Скетч: Код (C++): #include <LiquidCrystal.h> #include <AccelStepper.h> // select the pins used on the LCD panel LiquidCrystal lcd(8, 9, 4, 5, 6, 7); int stp = 4; //подключите 13 пин к step int dir = 7; //подключите 12 пин к dir int en = 2; AccelStepper stepper(1, stp, dir); // define some values used by the panel and buttons int lcd_key = 0; int adc_key_in = 0; #define btnRIGHT 0 #define btnUP 1 #define btnDOWN 2 #define btnLEFT 3 #define btnSELECT 4 #define btnNONE 5 int vol = 0; int done = 0; float mlsteps = 5;// милилтров за 1 оборот int rot = 1600; //шагов за оборот boolean start = false; // read the buttons int read_LCD_buttons() { 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; // when all others fail, return this... } void setup() { lcd.begin(16, 2); // start the library lcd.setCursor(0,0); lcd.print("Volume:"); lcd.setCursor(8,0); lcd.print(vol); lcd.setCursor(14,0); lcd.print("ml"); lcd.setCursor(0,1); lcd.print("Done:"); // выполненный объем lcd.setCursor(8,1); lcd.print(done); lcd.setCursor(14,1); lcd.print("ml"); stepper.setMinPulseWidth(10); stepper.setMaxSpeed(6000); stepper.setAcceleration(6000); } void loop() { if(start){ int allsteps = vol/mlsteps*rot;// расчитываем количество шагов: общий объем делим на объем за оборот и умножаем на кол-во шагов за оборот if(stepper.currentPosition() == allsteps){ // если готово int allrot = allsteps/rot; lcd.setCursor(8,1); lcd.print(allrot); stepper.setCurrentPosition(0); start = false; allsteps = 0; vol = 0; } stepper.runToNewPosition(allsteps); // stepper.moveTo(allsteps); // почему то медоенно вращается мотор, при использовании runToNewPosition куртит как бешаный //stepper.run(); } lcd.setCursor(0,1); // move to the begining of the second line lcd_key = read_LCD_buttons(); // read the buttons switch (lcd_key) // depending on which button was pushed, we perform an action { case btnRIGHT: { start = true; break; } case btnLEFT: { // lcd.print("LEFT "); vol = vol +10; lcd.setCursor(8,0); lcd.print(vol); delay(500); break; } case btnUP: { // lcd.print("UP "); vol = vol +1; lcd.setCursor(8,0); lcd.print(vol); delay(500); break; } case btnDOWN: { // lcd.print("DOWN "); vol = vol -1; lcd.setCursor(8,0); lcd.print(vol); delay(500); break; } case btnSELECT: { // lcd.print("SELECT"); vol = vol +100; lcd.setCursor(8,0); lcd.print(vol); delay(500); break; } case btnNONE: { // lcd.print("NONE "); break; } } }
Интересный дозатор. Пользуйся шпаргалкой. Размерность "INT" - переменная обозначающая количество шагов на оборот, больше 20 оборотов что произойдет?
я тоже намучался с этим) пока долго думал почему же при преодолении определенного значения переменной скетч начинает глючить. зато пришло понимание что если нужно фиксировать 0или1, можно использовать boolean (1бит-верно?) если 0..255, то используешь byte (1байт) если -32 768 до 32 767, то int (или 0 до 65535, unsigned int) (2байта) если от -2,147,483,648 до 2,147,483,647, то long (0 до 4,294,967,295, Unsigned long) (4байта) а до этого на все случаи жизни применял int...) в итге получилось хорошенько уменьшить вес скетча