Dmitry__, дануна, мне соседей и знакомых хватает - постоянно то на шашлыки тянут, то ещё куда. пару раз за несколько месяцев "немного" повыпивали и хватит, чтот меня за последний год почти не тянет даже на пиво.

![]() |
roboforum.ruТехнический форум по робототехнике. |
|
Dmitry__ писал(а):
slom, обещаешь всех тут напоить, если получится? Особенно angel-а?![]()
// Скетч для управления через блютус, Wild Thumper 6WD, на ардуино совместимом контролере TREX controller. реализовано движение и стрельба с водомета, захват клешней манипулятором.
// по вопросам и предложениям писать на почту slom1@list.ru
// новые фото и видео можно найти на www.шоуальянс.com
#include <BTCA2ALite.h>// Добавляем библиотеку блютус программы
#include <Servo.h> // Добавляем библиотеку серво
Servo myservoH; // Горизонтальная серва углы от 0 до 180 (центровка 89)
Servo myservoV; // Вертикальная серва углы от 1 до 45
Servo myservoZ; // серва Клешня
Servo myservoR; // серва рука клешни
const int Z_SERVO_PIN = 5; // добовляем пин захвата
const int R_SERVO_PIN = 6; // добовляем пин руки манипулятора
const int H_SERVO_PIN = 7; // Горизонтальная серва подключена к пину 7
const int V_SERVO_PIN = 8; //Пин вертикального сервопривода 8
const float Z_L_ANGLE = 116; // Максимальные угл поворота башни налево
const float Z_R_ANGLE = 45; // Максимальные угл поворота башни направо
const float Z_DEF_ANGLE = 50; // Дефолтный угол (центровка)
const float R_L_ANGLE = 178; // Максимальные угл поднятия руки
const float R_R_ANGLE = 3; // Максимальные угл наклона руки
const float R_DEF_ANGLE = 160; // Дефолтный угол руки
const float H_L_ANGLE = 180; // Максимальные угл поворота башни налево
const float H_R_ANGLE = 0; // Максимальные угл поворота башни направо
const float H_DEF_ANGLE = 84; // Дефолтный угол (центровка)
const float V_U_ANGLE = 140; // Максимальные угл поворота башни вверх
const float V_D_ANGLE = 45; // Максимальные угл поворота башни вниз
const float V_DEF_ANGLE = 60; // Дефолтный угол (центровка)
//Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
const float V_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по вертикали.
const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
const float Z_STEP = 0.012; // шаг захвата
const float R_STEP = 0.012; // шаг руки
float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы
float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы
float curZAngle = Z_DEF_ANGLE; //
float curRAngle = R_DEF_ANGLE; //
bool moveServoVUp = false; //Флаг движения верт. сервы вверх
bool moveServoVDown = false; //Флаг движения верт. сервы вниз
bool moveServoHLeft = false; //Флаг движения гор. сервы влево
bool moveServoHRight = false; //Флаг движения гор. сервы вправо
bool moveServoZLeft = false; //Флаг движения гор. сервы влево
bool moveServoZRight = false; //Флаг движения гор. сервы вправо
bool moveServoRLeft = false; //Флаг движения гор. сервы влево
bool moveServoRRight = false; //Флаг движения гор. сервы вправо
btca2aLite btca2aLite; // Конструктор btca2aLite
// задаем пины для левого мотора
#define Dir_L 2
#define Pwm_L 3
#define Brake_L 4
// задаем пины для правого мотора
#define Dir_R 10
#define Pwm_R 11
#define Brake_R 9
// Задаем скорости для движения
byte MaxSpeed = 230; // Максимальная скорость
byte MinSpeed = 90; // Минимальная скорость
int forw_back = 0;
int righ_left = 0;
byte step_fb = 5; // Шаг изменения скорости движения вперед - назад
byte step_stop = 10; // Шаг изменения скорости остановки
byte step_rl = 10; // Шаг изменения скорости движения вправо - влево
byte step_dir = 10; // Шаг изменения скорости выравнивания
#define SHOT 12 // пин для водомета
enum States
{
WAITING,
READING,
RUNNING,
ERROR,
TIMEOUT
};
States state;
States onWait();
States onRead();
States onRun();
States onError();
States onTimeout();
void performServo(); // добовляем сервы
void setup(){
Serial.begin(9600); // Скорость BT и порта должна быть 9600
//Моторы
pinMode (Pwm_L, OUTPUT);
pinMode (Dir_L, OUTPUT);
pinMode (Brake_L, OUTPUT);
pinMode (Pwm_R, OUTPUT);
pinMode (Dir_R, OUTPUT);
pinMode (Brake_R, OUTPUT);
digitalWrite (Pwm_L, LOW);
digitalWrite (Pwm_R, LOW);
digitalWrite (Brake_L, LOW);
digitalWrite (Brake_R, LOW);
pinMode(SHOT, OUTPUT); // задаем выход для стрельбы водой
// устанавливаем пин как вывод управления сервой
myservoH.attach(H_SERVO_PIN);
myservoV.attach(V_SERVO_PIN);
myservoZ.attach(Z_SERVO_PIN);
myservoR.attach(R_SERVO_PIN);
myservoH.write(curHAngle);
myservoV.write(curVAngle);
myservoZ.write(curZAngle);
myservoR.write(curRAngle);
//Светодиод
pinMode(13, OUTPUT); // Инициализируем пин светодиода
digitalWrite(13, HIGH); // Светодиод выключен
}
void loop(){
btca2aLite.ReadCommand(); // Считывание принятых команд (кодов кнопок)
//Вызываем функцию управление сервами
performServo();
//этот код для меня темный лес, мне его дали для плавного старта и торможения моторов. если ехать вперед и резко нажать кнопку назад, машина продолжит ехать вперед, плавно остановиться и только потом поедет назад, это спасает редуктора от разрушения.
//если ктото знает что тут к чему, прокоментируйте пожалуйста, чтоб я тоже понимал :)
static unsigned long pre_millis = 0;
if(millis()-pre_millis > 50)
{
pre_millis = millis();
if(btca2aLite.ButtonPressed(KEYCODE_DPAD_UP))
{
forw_back += step_fb;
if(forw_back > 0 && forw_back < MinSpeed) forw_back = MinSpeed;
}
else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_DOWN))
{
forw_back -= step_fb;
if(forw_back < 0 && forw_back > MinSpeed*-1) forw_back = MinSpeed*-1;
}
else
{
if(forw_back < 0) forw_back += step_stop;
else if(forw_back > 0) forw_back -= step_stop;
if(abs(forw_back) < MinSpeed) forw_back = 0;
}
forw_back = constrain(forw_back, MaxSpeed*-1, MaxSpeed);
if(btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT))
{
righ_left += step_rl;
if(righ_left > 0 && righ_left < MinSpeed) righ_left = MinSpeed;
}
else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT))
{
righ_left -= step_rl;
if(righ_left < 0 && righ_left > MinSpeed*-1) righ_left = MinSpeed*-1;
}
else
{
if(righ_left < 0) righ_left += step_dir;
else if(righ_left > 0) righ_left -= step_dir;
if(abs(righ_left) < MinSpeed) righ_left = 0;
}
righ_left = constrain(righ_left, MaxSpeed*-1, MaxSpeed);
int pwm_l = forw_back + righ_left;
int pwm_r = forw_back - righ_left;
pwm_l = constrain(pwm_l, MaxSpeed*-1, MaxSpeed);
pwm_r = constrain(pwm_r, MaxSpeed*-1, MaxSpeed);
digitalWrite(Dir_L, (pwm_l<0)?0:1);
digitalWrite(Dir_R, (pwm_r<0)?0:1);
analogWrite(Pwm_L, abs(pwm_l));
analogWrite(Pwm_R, abs(pwm_r));
}
//дальше идут кнопки управления
//-------— включение насоса —-------------
if (btca2aLite.ButtonPressed(KEYCODE_BUTTON_SELECT))
{
digitalWrite (SHOT, HIGH);
}
//-------— выключение насоса происходит автоматически после отпускания кнопки—-------------
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_SELECT))
{
digitalWrite (SHOT, LOW);
}
if(btca2aLite.Button(KEYCODE_BUTTON_START)) // алгоритм автоматического хватания предметов
{
/* шаг вперед, отключил....
digitalWrite (Dir_L, HIGH);
analogWrite (Pwm_L, 150);
digitalWrite (Dir_R, HIGH);
analogWrite (Pwm_R, 150);
delay (100);
// потом стоп
analogWrite (Pwm_L, 0);
analogWrite (Pwm_R, 0);
delay (500);
*/
myservoZ.write(45);; // Клешня разжимается
myservoR.write(3);; // рука клешни опускаем
delay(2000); /* ждем 2 секунды, */
myservoZ.write(116);; // Клешня сжимаем
delay(1000); /* ждем 1 секунду, */
myservoR.write(170);; // рука клешни поднимаем
delay(1000); /* ждем */
myservoZ.write(45);; // Клешня разжимаем
}
//--------— Повороты серв при нажатии кнопок —-------------
if(btca2aLite.Button(KEYCODE_BUTTON_X)) // поворот водомета вниз
{
moveServoVDown = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_A)) // поворот водомета направо
{
moveServoHRight = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_B)) // поворот водомета вверх
{
moveServoVUp = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_Y)) // поворот водомета налево
{
moveServoHLeft = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_R1)) // зхахват сжать
{
moveServoZLeft = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_R2)) // захват разжать
{
moveServoZRight = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_L1)) // рука клешни вниз
{
moveServoRLeft = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_L2)) // рука клешни вверх
{
moveServoRRight = true;
}
//--------— чтобы сервы не продолжали движения при отжатых кнопках —-------------
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_X))
{
moveServoVDown = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_B))
{
moveServoVUp = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_A))
{
moveServoHRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_Y))
{
moveServoHLeft = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_R2))
{
moveServoZRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_R1))
{
moveServoZLeft = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_L2))
{
moveServoRRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_L1))
{
moveServoRLeft = false;
}
//----------------— Стоп —---------------------
// Если не нажата ни одна кнопка курсора происходит остановка, скорость 0 для каждого мотора
if (btca2aLite.ButtonReleased(KEYCODE_DPAD_UP) && btca2aLite.ButtonReleased(KEYCODE_DPAD_DOWN) && btca2aLite.ButtonReleased(KEYCODE_DPAD_LEFT) && btca2aLite.ButtonReleased(KEYCODE_DPAD_RIGHT)){
analogWrite (Pwm_L, 0);
analogWrite (Pwm_R, 0);
}
}
//Функция управления сервоприводами (вызывается в теле loop на каждой итерации)
//Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения
//Флаги устанавливаются согласно поступившим символам управления сервами
void performServo()
{
//Установлен флаг движения вверх и текущий угол не максимальный
if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
{
//К текущему верт. углу прибавляем шаг
curVAngle += V_STEP;
}
//Установлен флаг движения вниз и текущий угол не минимален
else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
{
//От текущего верт. угла отнимаем шаг
curVAngle -= V_STEP;
}
//Установлен флаг движения влево и текущий угол не максимален
if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
{
//К текущему гор. углу прибавляем гор. шаг
curHAngle += H_STEP;
}
//Установлен флаг движения вправо и текущий угол не минимален
else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
{
//От текущего угла отнимаем гор. шаг
curHAngle -= H_STEP;
}
//Установлен
if (moveServoZLeft && curZAngle + Z_STEP <= Z_L_ANGLE)
{
//К текущему гор. углу прибавляем гор. шаг
curZAngle += Z_STEP;
}
//Установлен флаг движения вправо и текущий угол не минимален
else if (moveServoZRight && curZAngle - Z_STEP >= Z_R_ANGLE)
{
//От текущего угла отнимаем гор. шаг
curZAngle -= Z_STEP;
}
//Установлен
if (moveServoRLeft && curRAngle + R_STEP <= R_L_ANGLE)
{
//К текущему гор. углу прибавляем гор. шаг
curRAngle += R_STEP;
}
//Установлен флаг движения вправо и текущий угол не минимален
else if (moveServoRRight && curRAngle - R_STEP >= R_R_ANGLE)
{
//От текущего угла отнимаем гор. шаг
curRAngle -= R_STEP;
}
//Если было движние по вертикали
if (moveServoVUp || moveServoVDown)
{
myservoV.write(curVAngle);
}
//Если было движение по горизонтали
if (moveServoHLeft || moveServoHRight)
{
myservoH.write(curHAngle);
}
if (moveServoZLeft || moveServoZRight)
{
myservoZ.write(curZAngle);
}
if (moveServoRLeft || moveServoRRight)
{
myservoR.write(curRAngle);
}
}
Angel71 писал(а): чтот меня за последний год почти не тянет даже на пиво.поржал с того примера кода. ладно, скучно с вами, уйду я от вас.
Angel71 писал(а): разницу между кормить постоянно и дать удочку, что бы сами еду добывали, понимаете?
slom писал(а):вас я бы угостил хорошим пивом или чем покрепче
Found Controller, configured successful pressures = false
rumble = false
Try out all the buttons, X will vibrate the controller, faster as you press harder;
holding L1 or R1 will print out the analog stick values.
Note: Go to www.billporter.info for updates and to report bugs.
DualShock Controller found R2 pressed
R2 pressed
R2 pressed
L2 pressed
L2 pressed
Stick Values:116,255,128,255
Stick Values:255,255,255,255
Stick Values:255,255,128,255
Stick Values:120,255,128,255
Stick Values:211,255,128,255
L3 pressed
R3 pressed
L2 pressed
Stick Values:120,255,131,255
Stick Values:120,255,138,255
Stick Values:255,255,255,255
Dmitry__ писал(а):slom писал(а):вас я бы угостил хорошим пивом или чем покрепче
Kxe, смотри, я злопамятный, ведь попрусь в Севастополь за пивом![]()
А ты уверен, что после "наигрался" с этим джоем он тебя будет устраивать? Больше 15 метров управления на них не получить. Ну можно еще поколхозить внешние антенны, но это колхоз
Found Controller, configured successful pressures = false
rumble = false
Try out all the buttons, X will vibrate the controller, faster as you press harder;
holding L1 or R1 will print out the analog stick values.
Note: Go to www.billporter.info for updates and to report bugs.
Unknown Controller type found L2 pressed
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Start is being held
Start is being held
Start is being held
Select is being held
Select is being held
Select is being held
Select is being held
Select is being held
Select is being held
Select is being held
L2 pressed
Stick Values:127,110,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,110,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,110,127,128
Stick Values:127,109,127,128
Stick Values:127,108,127,128
Stick Values:127,110,127,128
Stick Values:127,108,127,128
Stick Values:127,108,127,128
Stick Values:127,108,127,128
Stick Values:127,108,127,128
Stick Values:127,109,127,128
Stick Values:127,109,127,128
Stick Values:127,110,127,128
Stick Values:127,110,127,128
Stick Values:127,108,127,128
Stick Values:127,108,127,128
Stick Values:127,108,127,128
Stick Values:127,108,127,128
Stick Values:127,108,127,128
Stick Values:127,108,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
L2 pressed
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
R2 pressed
R2 pressed
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,0,128
Stick Values:127,128,0,128
Stick Values:127,128,0,128
Stick Values:127,128,0,128
R3 pressed
L3 pressed
R3 pressed
L3 pressed
Circle just pressed
Square just released
X just changed
X just changed
Triangle pressed
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
Stick Values:127,128,127,128
DOWN held this hard: 0
DOWN held this hard: 0
DOWN held this hard: 0
DOWN held this hard: 0
DOWN held this hard: 0
Up held this hard: 0
Up held this hard: 0
Up held this hard: 0
LEFT held this hard: 0
LEFT held this hard: 0
LEFT held this hard: 0
Right held this hard: 0
Right held this hard: 0
Right held this hard: 0
Select is being held
Select is being held
Select is being held
Start is being held
Start is being held
Start is being held
Start is being held
R3 pressed
Stick Values:127,107,127,128
Stick Values:127,107,127,128
Stick Values:127,107,127,128
Stick Values:127,107,127,128
Stick Values:127,107,127,128
Stick Values:127,107,127,128
Stick Values:127,107,127,128
Stick Values:127,107,127,128
#include <PS2X_lib.h> //спец библиотека для работы с пультом сони пс2 for v1.6
#include <Servo.h>
PS2X ps2x;
int PS2 = 0;
Servo LXservo; // тут задаем имя сервы эта по оси х...
Servo LYservo;
#define L_dir 2 //пины для драйвера мотора
#define L_pwm 3
#define R_dir 4
#define R_pwm 5
int mass[4]; //здесь будем хранить значения для скоростей и направлений
//mass[0] лев.напр.
//mass[1] лев.скор.
//mass[2] прав.напр.
//mass[3] прав.скор.
void setup(){
LXservo.attach(8); //пины серв
LYservo.attach(6);
PS2 = ps2x.config_gamepad(13,11,10,12, true, true); //Настройка выводов: (clock, command, attention, data, true, true)
pinMode(L_dir, OUTPUT);
pinMode(L_pwm, OUTPUT);
pinMode(R_dir, OUTPUT);
pinMode(R_pwm, OUTPUT);
}
void loop(){
LXservo.write(map(ps2x.Analog(PSS_LX), 255, 0, 0, 180)); ; // мап - это интересная функция которая очень просто и без танцев с бубном переводит значения положения джойстика в градусы для вращения сервы.
delay(50);
ps2x.read_gamepad(false, 0);
LYservo.write(map(ps2x.Analog(PSS_LY), 0, 255, 0, 90)); ;
delay(50);
ps2x.read_gamepad(false, 0);
dir_pwm(ps2x.Analog(PSS_RY),2); //обрабатываем правый джойстик, это вроде как для мотора на колеса...
digitalWrite(R_dir, mass[2]);
analogWrite(R_pwm, mass[3]);
}
void dir_pwm(int Y, int n){ //Подпрограмма для обработки значений джойстика, тут непонятное чтото...
if (Y == 128){
mass[n+1] = 0;
}
if (Y >128){
mass[n+1] = Y*2-255;
mass[n] = 1;
}
if (Y <128){
mass[n+1] = 255-Y*2;
mass[n] = 0;
}
}
Scorpio писал(а):Я использую в таких случаях PCF8574
Scorpio писал(а):Я использую в таких случаях PCF8574
slom писал(а):насчет проверки работоспособности так это первым же делом сделал:
slom писал(а):главный вопрос, как перенести выполнение этих функций на другую дуню...
тоесть сейчас оно работает на 1й ардуине. а надо чтобы с 1й шли команды на 2ю и там уже крутились сервы и моторы...
void Bluetooth()
{
//============================================================= Bluetooth Control ===================================================
static byte d,e; // data and error bytes
if(Serial.available()>2) // Command is 3 bytes in length
{
d=Serial.read(); // read byte from buffer
if(d!=startbyte) // if byte is not a start byte (0x0F)
{
lmspeed=0; // bad data received
rmspeed=0; // set motor speeds to 0
e=0; // error flag reset
}
else
{
lmspeed=(int(Serial.read())-127)*2-1; // good data received
rmspeed=(int(Serial.read())-127)*2-1; // read values for left and right motors
}
}
else // less than 3 bytes in buffer
{
e++; // count program loops with less than 3 bytes in buffer
if(e>100) // assume lost signal if buffer less than 3 bytes for too long
{
lmspeed=0; // stop left motor
rmspeed=0; // stop right motor
e=0; // reset error counter
}
}
Motors(); // update motors
}
if (ps2x.NewButtonState()) { //будет TRUE если какая то кнопка изменила свой статус (Вкл. на Выкл. или Выкл. на Вкл.)
if(ps2x.Button(PSB_L3))
Serial.println("L3 pressed"); // L3 нажата
if(ps2x.Button(PSB_R3))
Serial.println("R3 pressed"); // R3 нажата
if(ps2x.Button(PSB_L2))
Serial.println("L2 pressed"); // L2 нажата
if(ps2x.Button(PSB_R2))
Serial.println("R2 pressed"); // R2 нажата
if(ps2x.Button(PSB_TRIANGLE))
Serial.println("Triangle pressed"); // Треугольник нажат
}
Serial.write(15);
Serial.write(32);
Serial.write(32);
char MyBytes[3] = {15, 32, 32}; //массив из 3 байт со значениями 15,32,32
Serial.write(MyBytes); //выводит 3 символа с кодами 15,32,32
if (ps2x.NewButtonState()) { //будет TRUE если какая то кнопка изменила свой статус (Вкл. на Выкл. или Выкл. на Вкл.)
if(ps2x.Button(PSB_L3))
{ // L3 нажата
Serial.write(15);
Serial.write(32);
Serial.write(32);
}
if(ps2x.Button(PSB_R3))
Serial.println("R3 pressed"); // R3 нажата
if(ps2x.Button(PSB_L2))
Serial.println("L2 pressed"); // L2 нажата
if(ps2x.Button(PSB_R2))
Serial.println("R2 pressed"); // R2 нажата
if(ps2x.Button(PSB_TRIANGLE))
Serial.println("Triangle pressed"); // Треугольник нажат
}
// Скетч для управления через блютус, Wild Thumper 6WD, на ардуино совместимом контролере TREX controller. реализовано движение и стрельба с водомета, захват клешней манипулятором.
// по вопросам и предложениям писать на почту slom1@list.ru
// новые фото и видео можно найти на www.шоуальянс.com
#include <BTCA2ALite.h>// Добавляем библиотеку блютус программы
#include <Servo.h> // Добавляем библиотеку серво
Servo myservoH; // Горизонтальная серва углы от 0 до 180 (центровка 89)
Servo myservoV; // Вертикальная серва углы от 1 до 45
Servo myservoZ; // серва Клешня
Servo myservoR; // серва рука клешни
const int Z_SERVO_PIN = 5; // добовляем пин захвата
const int R_SERVO_PIN = 6; // добовляем пин руки манипулятора
const int H_SERVO_PIN = 7; // Горизонтальная серва подключена к пину 7
const int V_SERVO_PIN = 8; //Пин вертикального сервопривода 8
const float Z_L_ANGLE = 116; // Максимальные угл поворота башни налево
const float Z_R_ANGLE = 45; // Максимальные угл поворота башни направо
const float Z_DEF_ANGLE = 50; // Дефолтный угол (центровка)
const float R_L_ANGLE = 178; // Максимальные угл поднятия руки
const float R_R_ANGLE = 3; // Максимальные угл наклона руки
const float R_DEF_ANGLE = 160; // Дефолтный угол руки
const float H_L_ANGLE = 180; // Максимальные угл поворота башни налево
const float H_R_ANGLE = 0; // Максимальные угл поворота башни направо
const float H_DEF_ANGLE = 84; // Дефолтный угол (центровка)
const float V_U_ANGLE = 140; // Максимальные угл поворота башни вверх
const float V_D_ANGLE = 45; // Максимальные угл поворота башни вниз
const float V_DEF_ANGLE = 60; // Дефолтный угол (центровка)
//Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
const float V_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по вертикали.
const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
const float Z_STEP = 0.012; // шаг захвата
const float R_STEP = 0.012; // шаг руки
float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы
float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы
float curZAngle = Z_DEF_ANGLE; //
float curRAngle = R_DEF_ANGLE; //
bool moveServoVUp = false; //Флаг движения верт. сервы вверх
bool moveServoVDown = false; //Флаг движения верт. сервы вниз
bool moveServoHLeft = false; //Флаг движения гор. сервы влево
bool moveServoHRight = false; //Флаг движения гор. сервы вправо
bool moveServoZLeft = false; //Флаг движения гор. сервы влево
bool moveServoZRight = false; //Флаг движения гор. сервы вправо
bool moveServoRLeft = false; //Флаг движения гор. сервы влево
bool moveServoRRight = false; //Флаг движения гор. сервы вправо
btca2aLite btca2aLite; // Конструктор btca2aLite
// задаем пины для левого мотора
#define Dir_L 2
#define Pwm_L 3
#define Brake_L 4
// задаем пины для правого мотора
#define Dir_R 10
#define Pwm_R 11
#define Brake_R 9
// Задаем скорости для движения
byte MaxSpeed = 230; // Максимальная скорость
byte MinSpeed = 90; // Минимальная скорость
int forw_back = 0;
int righ_left = 0;
byte step_fb = 5; // Шаг изменения скорости движения вперед - назад
byte step_stop = 10; // Шаг изменения скорости остановки
byte step_rl = 10; // Шаг изменения скорости движения вправо - влево
byte step_dir = 10; // Шаг изменения скорости выравнивания
#define SHOT 12 // пин для водомета
enum States
{
WAITING,
READING,
RUNNING,
ERROR,
TIMEOUT
};
States state;
States onWait();
States onRead();
States onRun();
States onError();
States onTimeout();
void performServo(); // добовляем сервы
void setup(){
Serial.begin(9600); // Скорость BT и порта должна быть 9600
//Моторы
pinMode (Pwm_L, OUTPUT);
pinMode (Dir_L, OUTPUT);
pinMode (Brake_L, OUTPUT);
pinMode (Pwm_R, OUTPUT);
pinMode (Dir_R, OUTPUT);
pinMode (Brake_R, OUTPUT);
digitalWrite (Pwm_L, LOW);
digitalWrite (Pwm_R, LOW);
digitalWrite (Brake_L, LOW);
digitalWrite (Brake_R, LOW);
pinMode(SHOT, OUTPUT); // задаем выход для стрельбы водой
// устанавливаем пин как вывод управления сервой
myservoH.attach(H_SERVO_PIN);
myservoV.attach(V_SERVO_PIN);
myservoZ.attach(Z_SERVO_PIN);
myservoR.attach(R_SERVO_PIN);
myservoH.write(curHAngle);
myservoV.write(curVAngle);
myservoZ.write(curZAngle);
myservoR.write(curRAngle);
//Светодиод
pinMode(13, OUTPUT); // Инициализируем пин светодиода
digitalWrite(13, HIGH); // Светодиод выключен
}
void loop(){
btca2aLite.ReadCommand(); // Считывание принятых команд (кодов кнопок)
//Вызываем функцию управление сервами
performServo();
//этот код для меня темный лес, мне его дали для плавного старта и торможения моторов. если ехать вперед и резко нажать кнопку назад, машина продолжит ехать вперед, плавно остановиться и только потом поедет назад, это спасает редуктора от разрушения.
//если ктото знает что тут к чему, прокоментируйте пожалуйста, чтоб я тоже понимал :)
static unsigned long pre_millis = 0;
if(millis()-pre_millis > 50)
{
pre_millis = millis();
if(btca2aLite.ButtonPressed(KEYCODE_DPAD_UP))
{
forw_back += step_fb;
if(forw_back > 0 && forw_back < MinSpeed) forw_back = MinSpeed;
}
else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_DOWN))
{
forw_back -= step_fb;
if(forw_back < 0 && forw_back > MinSpeed*-1) forw_back = MinSpeed*-1;
}
else
{
if(forw_back < 0) forw_back += step_stop;
else if(forw_back > 0) forw_back -= step_stop;
if(abs(forw_back) < MinSpeed) forw_back = 0;
}
forw_back = constrain(forw_back, MaxSpeed*-1, MaxSpeed);
if(btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT))
{
righ_left += step_rl;
if(righ_left > 0 && righ_left < MinSpeed) righ_left = MinSpeed;
}
else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT))
{
righ_left -= step_rl;
if(righ_left < 0 && righ_left > MinSpeed*-1) righ_left = MinSpeed*-1;
}
else
{
if(righ_left < 0) righ_left += step_dir;
else if(righ_left > 0) righ_left -= step_dir;
if(abs(righ_left) < MinSpeed) righ_left = 0;
}
righ_left = constrain(righ_left, MaxSpeed*-1, MaxSpeed);
int pwm_l = forw_back + righ_left;
int pwm_r = forw_back - righ_left;
pwm_l = constrain(pwm_l, MaxSpeed*-1, MaxSpeed);
pwm_r = constrain(pwm_r, MaxSpeed*-1, MaxSpeed);
digitalWrite(Dir_L, (pwm_l<0)?0:1);
digitalWrite(Dir_R, (pwm_r<0)?0:1);
analogWrite(Pwm_L, abs(pwm_l));
analogWrite(Pwm_R, abs(pwm_r));
}
//дальше идут кнопки управления
//-------— включение насоса —-------------
if (btca2aLite.ButtonPressed(KEYCODE_BUTTON_SELECT))
{
digitalWrite (SHOT, HIGH);
}
//-------— выключение насоса происходит автоматически после отпускания кнопки—-------------
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_SELECT))
{
digitalWrite (SHOT, LOW);
}
if(btca2aLite.Button(KEYCODE_BUTTON_START)) // алгоритм автоматического хватания предметов
{
/* шаг вперед, отключил....
digitalWrite (Dir_L, HIGH);
analogWrite (Pwm_L, 150);
digitalWrite (Dir_R, HIGH);
analogWrite (Pwm_R, 150);
delay (100);
// потом стоп
analogWrite (Pwm_L, 0);
analogWrite (Pwm_R, 0);
delay (500);
*/
myservoZ.write(45);; // Клешня разжимается
myservoR.write(3);; // рука клешни опускаем
delay(2000); /* ждем 2 секунды, */
myservoZ.write(116);; // Клешня сжимаем
delay(1000); /* ждем 1 секунду, */
myservoR.write(170);; // рука клешни поднимаем
delay(1000); /* ждем */
myservoZ.write(45);; // Клешня разжимаем
}
//--------— Повороты серв при нажатии кнопок —-------------
if(btca2aLite.Button(KEYCODE_BUTTON_X)) // поворот водомета вниз
{
moveServoVDown = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_A)) // поворот водомета направо
{
moveServoHRight = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_B)) // поворот водомета вверх
{
moveServoVUp = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_Y)) // поворот водомета налево
{
moveServoHLeft = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_R1)) // зхахват сжать
{
moveServoZLeft = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_R2)) // захват разжать
{
moveServoZRight = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_L1)) // рука клешни вниз
{
moveServoRLeft = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_L2)) // рука клешни вверх
{
moveServoRRight = true;
}
//--------— чтобы сервы не продолжали движения при отжатых кнопках —-------------
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_X))
{
moveServoVDown = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_B))
{
moveServoVUp = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_A))
{
moveServoHRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_Y))
{
moveServoHLeft = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_R2))
{
moveServoZRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_R1))
{
moveServoZLeft = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_L2))
{
moveServoRRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_L1))
{
moveServoRLeft = false;
}
//----------------— Стоп —---------------------
// Если не нажата ни одна кнопка курсора происходит остановка, скорость 0 для каждого мотора
if (btca2aLite.ButtonReleased(KEYCODE_DPAD_UP) && btca2aLite.ButtonReleased(KEYCODE_DPAD_DOWN) && btca2aLite.ButtonReleased(KEYCODE_DPAD_LEFT) && btca2aLite.ButtonReleased(KEYCODE_DPAD_RIGHT)){
analogWrite (Pwm_L, 0);
analogWrite (Pwm_R, 0);
}
}
//Функция управления сервоприводами (вызывается в теле loop на каждой итерации)
//Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения
//Флаги устанавливаются согласно поступившим символам управления сервами
void performServo()
{
//Установлен флаг движения вверх и текущий угол не максимальный
if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
{
//К текущему верт. углу прибавляем шаг
curVAngle += V_STEP;
}
//Установлен флаг движения вниз и текущий угол не минимален
else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
{
//От текущего верт. угла отнимаем шаг
curVAngle -= V_STEP;
}
//Установлен флаг движения влево и текущий угол не максимален
if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
{
//К текущему гор. углу прибавляем гор. шаг
curHAngle += H_STEP;
}
//Установлен флаг движения вправо и текущий угол не минимален
else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
{
//От текущего угла отнимаем гор. шаг
curHAngle -= H_STEP;
}
//Установлен
if (moveServoZLeft && curZAngle + Z_STEP <= Z_L_ANGLE)
{
//К текущему гор. углу прибавляем гор. шаг
curZAngle += Z_STEP;
}
//Установлен флаг движения вправо и текущий угол не минимален
else if (moveServoZRight && curZAngle - Z_STEP >= Z_R_ANGLE)
{
//От текущего угла отнимаем гор. шаг
curZAngle -= Z_STEP;
}
//Установлен
if (moveServoRLeft && curRAngle + R_STEP <= R_L_ANGLE)
{
//К текущему гор. углу прибавляем гор. шаг
curRAngle += R_STEP;
}
//Установлен флаг движения вправо и текущий угол не минимален
else if (moveServoRRight && curRAngle - R_STEP >= R_R_ANGLE)
{
//От текущего угла отнимаем гор. шаг
curRAngle -= R_STEP;
}
//Если было движние по вертикали
if (moveServoVUp || moveServoVDown)
{
myservoV.write(curVAngle);
}
//Если было движение по горизонтали
if (moveServoHLeft || moveServoHRight)
{
myservoH.write(curHAngle);
}
if (moveServoZLeft || moveServoZRight)
{
myservoZ.write(curZAngle);
}
if (moveServoRLeft || moveServoRRight)
{
myservoR.write(curRAngle);
}
}
// Скетч для управления через блютус, Wild Thumper 6WD, на ардуино совместимом контролере TREX controller. реализовано движение и стрельба с водомета.
#include <BTCA2ALite.h>// Добавляем библиотеку блютус программы
#include <Servo.h> // Добавляем библиотеку серво
Servo myservoH; // Горизонтальная серва углы от 0 до 180 (центровка 89)
Servo myservoV; // Вертикальная серва углы от 1 до 45
const int H_SERVO_PIN = 7; // Горизонтальная серва подключена к пину 7
const int V_SERVO_PIN = 8; //Пин вертикального сервопривода 8
const float H_L_ANGLE = 180; // Максимальные угл поворота башни налево
const float H_R_ANGLE = 0; // Максимальные угл поворота башни направо
const float H_DEF_ANGLE = 89; // Дефолтный угол (центровка)
const float V_U_ANGLE = 45; // Максимальные угл поворота башни вверх
const float V_D_ANGLE = 0; // Максимальные угл поворота башни вниз
const float V_DEF_ANGLE = 15; // Дефолтный угол (центровка)
//Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
const float V_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по вертикали.
const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы
float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы
bool moveServoVUp = false; //Флаг движения верт. сервы вверх
bool moveServoVDown = false; //Флаг движения верт. сервы вниз
bool moveServoHLeft = false; //Флаг движения гор. сервы влево
bool moveServoHRight = false; //Флаг движения гор. сервы вправо
btca2aLite btca2aLite; // Конструктор btca2aLite
// Задаем скорости для движения
int Speed = 80; // Текущая максимальная скорость
int TSpeed = 150; // Скорость медленного мотора при повороте
int RLSpeed = 200; // Скорость танкоаого разворота
// задаем пины для левого мотора
#define Dir_L 2
#define Pwm_L 3
#define Brake_L 4
// задаем пины для правого мотора
#define Dir_R 10
#define Pwm_R 11
#define Brake_R 9
#define SHOT 12 // пин для водомета
enum States
{
WAITING,
READING,
RUNNING,
ERROR,
TIMEOUT
};
States state;
States onWait();
States onRead();
States onRun();
States onError();
States onTimeout();
void performServo(); // добовляем сервы
void setup(){
Serial.begin(9600); // Скорость BT и порта должна быть 9600
//Моторы
pinMode (Pwm_L, OUTPUT);
pinMode (Dir_L, OUTPUT);
pinMode (Brake_L, OUTPUT);
pinMode (Pwm_R, OUTPUT);
pinMode (Dir_R, OUTPUT);
pinMode (Brake_R, OUTPUT);
digitalWrite (Pwm_L, LOW);
digitalWrite (Pwm_R, LOW);
digitalWrite (Brake_L, LOW);
digitalWrite (Brake_R, LOW);
pinMode(SHOT, OUTPUT); // задаем выход для стрельбы водой
// устанавливаем пин как вывод управления сервой
myservoH.attach(H_SERVO_PIN);
myservoV.attach(V_SERVO_PIN);
myservoH.write(curHAngle);
myservoV.write(curVAngle);
//Светодиод
pinMode(13, OUTPUT); // Инициализируем пин светодиода
digitalWrite(13, HIGH); // Светодиод выключен
}
void loop(){
btca2aLite.ReadCommand(); // Считывание принятых команд (кодов кнопок)
//Вызываем функцию управление сервами
performServo();
//--------— Движение Вперед —-------------
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_UP)) // Едет вперед если нажат курсор ВПЕРЕД
{
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT)){ // Поворот направо при нажатии курсора ВПЕРЕД и ВЛЕВО
digitalWrite (Dir_L, HIGH);
analogWrite (Pwm_L, TSpeed);
digitalWrite (Dir_R, HIGH);
analogWrite (Pwm_R, Speed);
}
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT)){ // Поворот налево при нажатии курсора ВПЕРЕД и ВПРАВО
digitalWrite (Dir_L, HIGH);
analogWrite (Pwm_L, Speed);
digitalWrite (Dir_R, HIGH);
analogWrite (Pwm_R, TSpeed);
}
digitalWrite (Dir_L, HIGH);
analogWrite (Pwm_L, Speed);
digitalWrite (Dir_R, HIGH);
analogWrite (Pwm_R, Speed);
}
//-------— Движение Назад —-------------
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_DOWN)) // Едет назад если нажат курсор НАЗАД
{
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT)){ // Поворот налево при нажатии курсора НАЗАД и ВЛЕВО
digitalWrite (Dir_L, LOW);
analogWrite (Pwm_L, TSpeed);
digitalWrite (Dir_R, LOW);
analogWrite (Pwm_R, Speed);
}
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT)){ // Поворот направо при нажатии курсора НАЗАД и ВПРАВО
digitalWrite (Dir_L, LOW);
analogWrite (Pwm_L, Speed);
digitalWrite (Dir_R, LOW);
analogWrite (Pwm_R, TSpeed);
}
digitalWrite (Dir_L, LOW);
analogWrite (Pwm_L, Speed);
digitalWrite (Dir_R, LOW);
analogWrite (Pwm_R, Speed);
}
//-------— Движение Влево (Танковый разворот) —-------------
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT )) // Едет вперед если нажат курсор ВПЕРЕД
{
digitalWrite (Dir_L, LOW);
analogWrite (Pwm_L, RLSpeed);
digitalWrite (Dir_R, HIGH);
analogWrite (Pwm_R, RLSpeed);
}
//-------— Движение Вправо (Танковый разворот) —-------------
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT)) // Едет вперед если нажат курсор ВПЕРЕД
{
digitalWrite (Dir_L, HIGH);
analogWrite (Pwm_L, RLSpeed);
digitalWrite (Dir_R, LOW);
analogWrite (Pwm_R, RLSpeed);
}
//-------— движение в право —-------------
if (btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT)) // Едет вперед если нажат курсор ВПЕРЕД
{
digitalWrite (Dir_L, HIGH);
analogWrite (Pwm_L, RLSpeed);
digitalWrite (Dir_R, LOW);
analogWrite (Pwm_R, RLSpeed);
}
//---------- Переключение скоростей —-------------
if(btca2aLite.Button(KEYCODE_BUTTON_START)) // ТУРБО режимпри нажатии кнопки START
{
Speed = 200;
}
if(btca2aLite.Button(KEYCODE_BUTTON_R2)) // 4-я Скорость при нажатии кнопки R2
{
Speed = 150;
}
if(btca2aLite.Button(KEYCODE_BUTTON_R1)) // 3-я Скорость при нажатии кнопки R1
{
Speed = 120;
}
if(btca2aLite.Button(KEYCODE_BUTTON_L2)) // 2-я Скорость при нажатии кнопки L2
{
Speed = 90;
}
if(btca2aLite.Button(KEYCODE_BUTTON_L1)) // 1-я Скорость при нажатии кнопки L2
{
Speed = 70;
}
//-------— включение насоса —-------------
if (btca2aLite.ButtonPressed(KEYCODE_BUTTON_SELECT))
{
digitalWrite (SHOT, HIGH);
}
//-------— выключение насоса происходит автоматически после отпускания кнопки—-------------
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_SELECT))
{
digitalWrite (SHOT, LOW);
}
//--------— Повороты серв при нажатии кнопок —-------------
if(btca2aLite.Button(KEYCODE_BUTTON_X)) // servoV вниз
{
moveServoVDown = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_A)) // servoH движется к 0
{
moveServoHRight = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_B)) // servoV вверх
{
moveServoVUp = true;
}
if(btca2aLite.Button(KEYCODE_BUTTON_Y)) // servoH движется к 180
{
moveServoHLeft = true;
}
//--------— чтобы сервы не продолжали движения при отжатых кнопках —-------------
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_X))
{
moveServoVDown = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_B))
{
moveServoVUp = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_A))
{
moveServoHRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_Y))
{
moveServoHLeft = false;
}
//----------------— Стоп —---------------------
// Если не нажата ни одна кнопка курсора происходит остановка, скорость 0 для каждого мотора
if (btca2aLite.ButtonReleased(KEYCODE_DPAD_UP) && btca2aLite.ButtonReleased(KEYCODE_DPAD_DOWN) && btca2aLite.ButtonReleased(KEYCODE_DPAD_LEFT) && btca2aLite.ButtonReleased(KEYCODE_DPAD_RIGHT)){
analogWrite (Pwm_L, 0);
analogWrite (Pwm_R, 0);
}
}
//Функция управления сервоприводами (вызывается в теле loop на каждой итерации)
//Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения
//Флаги устанавливаются согласно поступившим символам управления сервами
void performServo()
{
//Установлен флаг движения вверх и текущий угол не максимальный
if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
{
//К текущему верт. углу прибавляем шаг
curVAngle += V_STEP;
}
//Установлен флаг движения вниз и текущий угол не минимален
else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
{
//От текущего верт. угла отнимаем шаг
curVAngle -= V_STEP;
}
//Установлен флаг движения влево и текущий угол не максимален
if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
{
//К текущему гор. углу прибавляем гор. шаг
curHAngle += H_STEP;
}
//Установлен флаг движения вправо и текущий угол не минимален
else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
{
//От текущего угла отнимаем гор. шаг
curHAngle -= H_STEP;
}
//Если было движние по вертикали
if (moveServoVUp || moveServoVDown)
{
myservoV.write(curVAngle);
}
//Если было движение по горизонтали
if (moveServoHLeft || moveServoHRight)
{
myservoH.write(curHAngle);
}
}
Ой, чо-то сложно обьяснил
ещё пару дней и доберётесь до тех несчастных пары строк на предыдущих страницах. в первом варианте там осталось только структуру сделать и обьединение для сериализации, во втором вообще ничего добавлять не нужно.
slom писал(а):но не сложно ли это? я думал можно както попроще...
например при нажатии на джойстике кнопки вперед, посылать чтото типо текста "vpered" а на 2й дуине зарание задать список команд, если принятая "vpered" есть в списке то выполнить действие к ней привязанное...
Данные: 128
128 - 128 = 0.
Значит посылаем команду "stop"
Данные: 129
129 - 128 = 1
Ага, число положительное, значит посылаем команду "wpered"
Потом посылаем "1"
Данные: 100
100 - 128
Ага, число отрицательно, значит посылаем команду "nazad"
Теперь надо преобразовать данные из дополнительной формы или поменять порядок вычитаемых данных:
128 - 100 = 28
Послать 28
Принять число от джойстика
Послать байт на 2-ю дуину.
/*This is an example of the EasyTransfer Library 2way communications.
This sketch is for the Arduino with the servo attached to pin 9.
The other Arduino has a potentiometer attached to analog pin 0.
Both have a putton attached to pin 12 and output a status using the LED on pin 13.
The idea is each arduino will read the status of the button attached to it, and send it
to the other Arduino, which will toggle it's LED based on the others button. The button
should connect pin 12 to ground when pushed.
And the Arduino with the potentiometer will send it's value to the one with the servo.
The servo will move to the position based on the potentiometer.
*/
#include <Servo.h>
#include <EasyTransfer.h>
//create two objects
EasyTransfer ETin, ETout;
//create servo
Servo myservo;
struct RECEIVE_DATA_STRUCTURE{
//put your variable definitions here for the data you want to receive
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int buttonstate;
int servoval;
};
struct SEND_DATA_STRUCTURE{
//put your variable definitions here for the data you want to receive
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int buttonstate;
};
//give a name to the group of data
RECEIVE_DATA_STRUCTURE rxdata;
SEND_DATA_STRUCTURE txdata;
void setup(){
Serial.begin(9600);
//start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
ETin.begin(details(rxdata), &Serial);
ETout.begin(details(txdata), &Serial);
pinMode(13, OUTPUT);
pinMode(12, INPUT);
//enable pull-up
digitalWrite(12, HIGH);
myservo.attach(9);
}
void loop(){
//first, lets read our button and store it in our data structure
if(!digitalRead(12))
txdata.buttonstate = HIGH;
else
txdata.buttonstate = LOW;
//then we will go ahead and send that data out
ETout.sendData();
//there's a loop here so that we run the recieve function more often then the
//transmit function. This is important due to the slight differences in
//the clock speed of different Arduinos. If we didn't do this, messages
//would build up in the buffer and appear to cause a delay.
for(int i=0; i<5; i++){
//remember, you could use an if() here to check for new data, this time it's not needed.
ETin.receiveData();
//set our LED on or off based on what we received from the other Arduino
digitalWrite(13, rxdata.buttonstate);
//set our servo position based on what we received from the other Arduino
//we will also map the ADC value to a servo value
myservo.write(map(rxdata.servoval, 0, 1023, 0, 179));
//delay
delay(10);
}
//delay for good measure
delay(10);
}
Вернуться в Arduino и другие Xduino
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3