управление сервами
- Войдите на сайт для отправки комментариев
Чт, 02/10/2014 - 22:33
Всем драсти. Есть такое устройство на ардуине: хедтрекер. Суть: управление сервами в зависимости от пространственного положения платы с датчиками, которая крепится на голову.
http://www.rcgroups.com/forums/showthread.php?t=1677559&highlight=headtrack
засада в том, что все это засовывается в один PPM сигнал, который через тренерский разъем подмешивается в основной сигнал с аппаратуры. Только срабатывает эта фишка на определенных типах аппаратур управления. Идея заключается в разнесении каналов управления сервами по разным выходам и сделать управление как вот здесь:
http://apmcopter.ru/apm/apm-setup/per-rezhimov-alekseya-kozina.html
надеюсь доступно расписал
И ЧЁ?
Подойдет, наверно, практически ко всем аппаратурам, имеющим хотя бы один аналоговый регулятор (переменный резистор) — «крутилку». Предполагается его замена на изготавливаемый переключатель.
проще говоря чтобы подключать к крутилке канала управления сервой
И ЧЁ?
хочу узнать есть ли возможность переделать исходник под поставленную задачу
ссылка на исходник
https://yadi.sk/d/E1E96t9jbnXQc
сам скетч
001
//-----------------------------------------------------------------------------
002
// Original project by Dennis Frie - 2012 - <a href="mailto:Dennis.frie@gmail.com">Dennis.frie@gmail.com</a>
003
// Discussion: <a href="http://www.rcgroups.com/forums/showthread.php?t=1677559" rel="nofollow">http://www.rcgroups.com/forums/showthread.php?t=1677559</a>
004
//
005
// Other contributors to this code:
006
// Mark Mansur (Mangus on rcgroups)
007
//
008
// Version history:
009
// - 0.01 - 0.08 - Dennis Frie - preliminary releases
010
// - 1.01 - April 2013 - Mark Mansur - code clean-up and refactoring, comments
011
// added. Added pause functionality, added settings retrieval commands.
012
// Minor optimizations.
013
//-----------------------------------------------------------------------------
014
015
#include <Wire.h>
016
#include "config.h"
017
#include "functions.h"
018
#include "sensors.h"
019
#include <EEPROM.h>
020
021
/*
022
Channel mapping/config for PPM out:
023
024
1 = PPM CHANNEL 1
025
2 = PPM CHANNEL 2
026
3 = PPM CHANNEL 3
027
4 = PPM CHANNEL 4
028
5 = PPM CHANNEL 5
029
6 = PPM CHANNEL 6
030
7 = PPM CHANNEL 7
031
8 = PPM CHANNEL 8
032
9 = PPM CHANNEL 9
033
10 = PPM CHANNEL 10
034
11 = PPM CHANNEL 11
035
12 = PPM CHANNEL 12
036
037
Mapping example:
038
$123456789111CH
039
*/
040
041
042
// Local file variables
043
//
044
int
frameNumber = 0;
// Frame count since last debug serial output
045
046
char
serial_data[101];
// Array for serial-data
047
unsigned
char
serial_index = 0;
// How many bytes have been received?
048
char
string_started = 0;
// Only saves data if string starts with right byte
049
unsigned
char
channel_mapping[13];
050
051
char
outputMag = 0;
// Stream magnetometer data to host
052
char
outputAcc = 0;
// Stream accelerometer data to host
053
char
outputMagAcc = 0;
// Stream mag and accell data (for calibration on PC)
054
char
outputTrack = 0;
// Stream angle data to host
055
056
// Keep track of button press
057
char
lastButtonState = 0;
// 0 is not pressed, 1 is pressed
058
unsigned
long
buttonDownTime = 0;
// the system time of the press
059
char
pauseToggled = 0;
// Used to make sure we toggle pause only once per hold
060
char
ht_paused = 0;
061
062
// External variables (defined in other files)
063
//
064
extern
unsigned
char
PpmIn_PpmOut[13];
065
extern
char
read_sensors;
066
extern
char
resetValues;
067
extern
char
tiltInverse;
068
extern
char
rollInverse;
069
extern
char
panInverse;
070
071
// Settings (Defined in sensors.cpp)
072
//
073
extern
float
tiltRollBeta;
074
extern
float
panBeta;
075
extern
float
gyroWeightTiltRoll;
076
extern
float
GyroWeightPan;
077
extern
int
servoPanCenter;
078
extern
int
servoTiltCenter;
079
extern
int
servoRollCenter;
080
extern
int
panMaxPulse;
081
extern
int
panMinPulse;
082
extern
int
tiltMaxPulse;
083
extern
int
tiltMinPulse;
084
extern
int
rollMaxPulse;
085
extern
int
rollMinPulse;
086
extern
float
panFactor;
087
extern
float
tiltFactor;
088
extern
float
rollFactor;
089
extern
unsigned
char
servoReverseMask;
090
extern
unsigned
char
htChannels[];
091
extern
float
gyroOff[];
092
extern
float
magOffset[];
093
extern
int
accOffset[];
094
// End settings
095
096
//--------------------------------------------------------------------------------------
097
// Func: setup
098
// Desc: Called by Arduino framework at initialization time. This sets up pins for I/O,
099
// initializes sensors, etc.
100
//--------------------------------------------------------------------------------------
101
void
setup
()
102
{
103
Serial
.begin(SERIAL_BAUD);
104
105
106
pinMode(9,OUTPUT);
107
digitalWrite(2,HIGH);
108
digitalWrite(3,HIGH);
109
110
// Set all other pins to input, for safety.
111
pinMode(0,INPUT);
112
pinMode(1,INPUT);
113
pinMode(2,INPUT);
114
pinMode(3,INPUT);
115
pinMode(6,INPUT);
116
pinMode(7,INPUT);
117
pinMode(8,INPUT);
118
119
// Set button pin to input:
120
pinMode(BUTTON_INPUT,INPUT);
121
122
// Set internal pull-up resistor.
123
digitalWrite(BUTTON_INPUT,HIGH);
124
125
digitalWrite(0,LOW);
// pull-down resistor
126
digitalWrite(1,LOW);
127
digitalWrite(2,HIGH);
128
digitalWrite(3,HIGH);
129
130
pinMode(ARDUINO_LED,OUTPUT);
// Arduino LED
131
digitalWrite(ARDUINO_LED, HIGH);
132
133
#if FATSHARK_HT_MODULE
134
pinMode(BUZZER,OUTPUT);
// Buzzer
135
digitalWrite(BUZZER, HIGH);
136
#endif
137
138
// Give it time to be noticed, then turn it off
139
delay(200);
// Note: only use delay here. This won't work when Timer0 is repurposed later.
140
digitalWrite(ARDUINO_LED, LOW);
141
142
#if FATSHARK_HT_MODULE
143
digitalWrite(BUZZER, LOW);
144
#endif
145
146
InitPWMInterrupt();
// Start PWM interrupt
147
Wire.begin();
// Start I2C
148
149
// If the device have just been programmed, write initial config/values to EEPROM:
150
if
(EEPROM.read(0) != 8)
151
{
152
//#if (DEBUG)
153
Serial
.println(
"New board - saving default values!"
);
154
//#endif
155
156
InitSensors();
157
#if (ALWAYS_CAL_GYRO)
158
SetGyroOffset();
159
#endif
160
161
SaveSettings();
162
SaveMagData();
163
SaveAccelData();
164
}
165
166
GetSettings();
// Get settings saved in EEPROM
167
InitSensors();
// Initialize I2C sensors
168
CalibrateMag();
169
ResetCenter();
170
InitTimerInterrupt();
// Start timer interrupt (for sensors)
171
}
172
173
//--------------------------------------------------------------------------------------
174
// Func: loop
175
// Desc: Called by the Arduino framework once per frame. Represents main program loop.
176
//--------------------------------------------------------------------------------------
177
void
loop
()
178
{
179
// Check input button for reset/pause request
180
char
buttonPressed = (digitalRead(BUTTON_INPUT) == 0);
181
182
if
( buttonPressed && lastButtonState == 0)
183
{
184
resetValues = 1;
185
buttonDownTime = 0;
186
lastButtonState = 1;
187
}
188
189
if
( buttonPressed )
190
{
191
if
( !pauseToggled && (buttonDownTime > BUTTON_HOLD_PAUSE_THRESH) )
192
{
193
// Pause/unpause
194
ht_paused = !ht_paused;
195
resetValues = 1;
196
pauseToggled = 1;
197
}
198
}
199
else
200
{
201
pauseToggled = 0;
202
lastButtonState = 0;
203
}
204
205
// All this is used for communication with GUI
206
//
207
if
(
Serial
.available())
208
{
209
if
(string_started == 1)
210
{
211
// Read incoming byte
212
serial_data[serial_index++] =
Serial
.read();
213
214
// If string ends with "CH" it's channel configuration, that have been received.
215
// String must always be 12 chars/bytes and ending with CH to be valid.
216
if
(serial_index == 14 &&
217
serial_data[serial_index-2] ==
'C'
&&
218
serial_data[serial_index-1] ==
'H'
)
219
{
220
// To keep it simple, we will not let the channels be 0-initialized, but
221
// start from 1 to match actual channels.
222
for
(unsigned
char
i = 0; i < 13; i++)
223
{
224
channel_mapping[i + 1] = serial_data[i] - 48;
225
226
// Update the dedicated PPM-in -> PPM-out array for faster performance.
227
if
((serial_data[i] - 48) < 14)
228
{
229
PpmIn_PpmOut[serial_data[i]-48] = i + 1;
230
}
231
}
232
233
Serial
.println(
"Channel mapping received"
);
234
235
// Reset serial_index and serial_started
236
serial_index = 0;
237
string_started = 0;
238
}
239
240
// Configure headtracker
241
else
if
(serial_data[serial_index-2] ==
'H'
&&
242
serial_data[serial_index-1] ==
'E'
)
243
{
244
// HT parameters are passed in from the PC in this order:
245
//
246
// 0 tiltRollBeta
247
// 1 panBeta
248
// 2 gyroWeightTiltRoll
249
// 3 GyroWeightPan
250
// 4 tiltFactor
251
// 5 panFactor
252
// 6 rollFactor
253
// 7 servoReverseMask
254
// 8 servoPanCenter
255
// 9 panMinPulse
256
// 10 panMaxPulse
257
// 11 servoTiltCenter
258
// 12 tiltMinPulse
259
// 13 tiltMaxPulse
260
// 14 servoRollCenter
261
// 15 rollMinPulse
262
// 16 rollMaxPulse
263
// 17 htChannels[0] // pan
264
// 18 htChannels[1] // tilt
265
// 19 htChannels[2] // roll
266
267
// Parameters from the PC client need to be scaled to match our local
268
// expectations
269
270
Serial
.println(
"HT config received:"
);
271
272
int
valuesReceived[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
273
int
comma_index = 0;
274
275
for
(unsigned
char
k = 0; k < serial_index - 2; k++)
276
{
277
// Looking for comma
278
if
(serial_data[k] == 44)
279
{
280
comma_index++;
281
}
282
else
283
{
284
valuesReceived[comma_index] = valuesReceived[comma_index] * 10 + (serial_data[k] - 48);
285
}
286
287
#if (DEBUG)
288
Serial
.print(serial_data[k]);
289
#endif
290
}
291
292
#if (DEBUG)
293
Serial
.println();
294
for
(unsigned
char
k = 0; k < comma_index+1; k++)
295
{
296
Serial
.print(valuesReceived[k]);
297
Serial
.print(
","
);
298
}
299
Serial
.println();
300
#endif
301
302
tiltRollBeta = (
float
)valuesReceived[0] / 100;
303
panBeta = (
float
)valuesReceived[1] / 100;
304
gyroWeightTiltRoll = (
float
)valuesReceived[2] / 100;
305
GyroWeightPan = (
float
)valuesReceived[3] / 100;
306
tiltFactor = (
float
)valuesReceived[4] / 10;
307
panFactor = (
float
)valuesReceived[5] / 10;
308
rollFactor = (
float
)valuesReceived[6] / 10;
309
310
servoReverseMask = (unsigned
char
)valuesReceived[7];
311
312
tiltInverse = 1;
313
rollInverse = 1;
314
panInverse = 1;
315
316
if
((servoReverseMask & HT_PAN_REVERSE_BIT) != 0)
317
{
318
panInverse = -1;
319
}
320
if
((servoReverseMask & HT_ROLL_REVERSE_BIT) != 0)
321
{
322
rollInverse = -1;
323
}
324
if
((servoReverseMask & HT_TILT_REVERSE_BIT) != 0)
325
{
326
tiltInverse = -1;
327
}
328
329
servoPanCenter = valuesReceived[8];
330
panMinPulse = valuesReceived[9];
331
panMaxPulse = valuesReceived[10];
332
333
servoTiltCenter = valuesReceived[11];
334
tiltMinPulse = valuesReceived[12];
335
tiltMaxPulse = valuesReceived[13];
336
337
servoRollCenter = valuesReceived[14];
338
rollMinPulse = valuesReceived[15];
339
rollMaxPulse = valuesReceived[16];
340
341
htChannels[0] = valuesReceived[17];
342
htChannels[1] = valuesReceived[18];
343
htChannels[2] = valuesReceived[19];
344
345
Serial
.println(htChannels[0]);
346
Serial
.println(htChannels[1]);
347
Serial
.println(htChannels[2]);
348
349
SaveSettings();
350
351
serial_index = 0;
352
string_started = 0;
353
}
// end configure headtracker
354
355
// Debug info
356
else
if
(serial_data[serial_index-5] ==
'D'
&&
357
serial_data[serial_index-4] ==
'E'
&&
358
serial_data[serial_index-3] ==
'B'
&&
359
serial_data[serial_index-2] ==
'U'
&&
360
serial_data[serial_index-1] ==
'G'
)
361
{
362
DebugOutput();
363
serial_index = 0;
364
string_started = 0;
365
}
366
367
// Firmware version requested
368
else
if
(serial_data[serial_index-4] ==
'V'
&&
369
serial_data[serial_index-3] ==
'E'
&&
370
serial_data[serial_index-2] ==
'R'
&&
371
serial_data[serial_index-1] ==
'S'
)
372
{
373
Serial
.print(
"FW: "
);
374
Serial
.println(FIRMWARE_VERSION_FLOAT, 2);
375
serial_index = 0;
376
string_started = 0;
377
}
378
379
// Start mag and accel data stream
380
else
if
(serial_data[serial_index-4] ==
'C'
&&
381
serial_data[serial_index-3] ==
'M'
&&
382
serial_data[serial_index-2] ==
'A'
&&
383
serial_data[serial_index-1] ==
'S'
)
384
{
385
outputMagAcc = 1;
386
outputMag = 0;
387
outputAcc = 0;
388
outputTrack = 0;
389
serial_index = 0;
390
string_started = 0;
391
}
392
393
// Stop mag and accel data stream
394
else
if
(serial_data[serial_index-4] ==
'C'
&&
395
serial_data[serial_index-3] ==
'M'
&&
396
serial_data[serial_index-2] ==
'A'
&&
397
serial_data[serial_index-1] ==
'E'
)
398
{
399
outputMagAcc = 0;
400
outputMag = 0;
401
outputTrack = 0;
402
outputAcc = 0;
403
serial_index = 0;
404
string_started = 0;
405
}
406
407
// Start magnetometer data stream
408
else
if
(serial_data[serial_index-4] ==
'C'
&&
409
serial_data[serial_index-3] ==
'A'
&&
410
serial_data[serial_index-2] ==
'S'
&&
411
serial_data[serial_index-1] ==
'T'
)
412
{
413
outputMag = 1;
414
outputMagAcc = 0;
415
outputAcc = 0;
416
outputTrack = 0;
417
serial_index = 0;
418
string_started = 0;
419
420
}
421
422
// Stop magnetometer data stream
423
else
if
(serial_data[serial_index-4] ==
'C'
&&
424
serial_data[serial_index-3] ==
'A'
&&
425
serial_data[serial_index-2] ==
'E'
&&
426
serial_data[serial_index-1] ==
'N'
)
427
{
428
outputMag = 0;
429
outputMagAcc = 0;
430
outputAcc = 0;
431
outputTrack = 0;
432
serial_index = 0;
433
string_started = 0;
434
}
435
436
// Start accelerometer data stream
437
else
if
(serial_data[serial_index-4] ==
'G'
&&
438
serial_data[serial_index-3] ==
'R'
&&
439
serial_data[serial_index-2] ==
'A'
&&
440
serial_data[serial_index-1] ==
'V'
)
441
{
442
outputAcc = 1;
443
outputMagAcc = 0;
444
outputMag = 0;
445
outputTrack = 0;
446
serial_index = 0;
447
string_started = 0;
448
}
449
450
// Stop accelerometer data stream
451
else
if
(serial_data[serial_index-4] ==
'G'
&&
452
serial_data[serial_index-3] ==
'R'
&&
453
serial_data[serial_index-2] ==
'E'
&&
454
serial_data[serial_index-1] ==
'N'
)
455
{
456
outputAcc = 0;
457
outputMag = 0;
458
outputMagAcc = 0;
459
outputTrack = 0;
460
serial_index = 0;
461
string_started = 0;
462
}
463
464
// Start tracking data stream
465
else
if
(serial_data[serial_index-4] ==
'P'
&&
466
serial_data[serial_index-3] ==
'L'
&&
467
serial_data[serial_index-2] ==
'S'
&&
468
serial_data[serial_index-1] ==
'T'
)
469
{
470
outputTrack = 1;
471
outputMagAcc = 0;
472
outputMag = 0;
473
outputAcc = 0;
474
serial_index = 0;
475
string_started = 0;
476
}
477
478
// Stop tracking data stream
479
else
if
(serial_data[serial_index-4] ==
'P'
&&
480
serial_data[serial_index-3] ==
'L'
&&
481
serial_data[serial_index-2] ==
'E'
&&
482
serial_data[serial_index-1] ==
'N'
)
483
{
484
outputTrack = 0;
485
outputMag = 0;
486
outputAcc = 0;
487
outputMagAcc = 0;
488
serial_index = 0;
489
string_started = 0;
490
}
491
492
// Save RAM settings to EEPROM
493
else
if
(serial_data[serial_index-4] ==
'S'
&&
494
serial_data[serial_index-3] ==
'A'
&&
495
serial_data[serial_index-2] ==
'V'
&&
496
serial_data[serial_index-1] ==
'E'
)
497
{
498
SaveSettings();
499
serial_index = 0;
500
string_started = 0;
501
}
502
503
// Calibrate gyro
504
else
if
(serial_data[serial_index-4] ==
'C'
&&
505
serial_data[serial_index-3] ==
'A'
&&
506
serial_data[serial_index-2] ==
'L'
&&
507
serial_data[serial_index-1] ==
'G'
)
508
{
509
SetGyroOffset();
510
SaveSettings();
511
512
Serial
.print(
"Gyro offset measured:"
);
513
Serial
.print(gyroOff[0]);
514
Serial
.print(
","
);
515
Serial
.print(gyroOff[1]);
516
Serial
.print(
","
);
517
Serial
.println(gyroOff[2]);
518
519
serial_index = 0;
520
string_started = 0;
521
}
522
523
// Store magnetometer offset
524
else
if
(serial_data[serial_index-3] ==
'M'
&&
525
serial_data[serial_index-2] ==
'A'
&&
526
serial_data[serial_index-1] ==
'G'
)
527
{
528
Serial
.println(serial_data);
529
int
valuesReceived[5] = {0,0,0,0,0};
530
int
comma_index = 0;
531
532
for
(unsigned
char
k = 0; k < serial_index - 3; k++)
533
{
534
// Looking for comma
535
if
(serial_data[k] == 44)
536
{
537
comma_index++;
538
}
539
else
540
{
541
valuesReceived[comma_index] = valuesReceived[comma_index] * 10 + (serial_data[k] - 48);
542
}
543
}
544
545
// Y and Z are swapped on purpose.
546
magOffset[0] = valuesReceived[0] - 2000;
547
magOffset[1] = valuesReceived[2] - 2000;
548
magOffset[2] = valuesReceived[1] - 2000;
549
550
serial_index = 0;
551
string_started = 0;
552
553
SaveMagData();
554
}
555
556
// Store accelerometer offset
557
else
if
(serial_data[serial_index-3] ==
'A'
&&
558
serial_data[serial_index-2] ==
'C'
&&
559
serial_data[serial_index-1] ==
'C'
)
560
{
561
Serial
.println(serial_data);
562
int
valuesReceived[5] = {0,0,0,0,0};
563
int
comma_index = 0;
564
for
(unsigned
char
k = 0; k < serial_index - 3; k++)
565
{
566
// Looking for comma
567
if
(serial_data[k] == 44)
568
{
569
comma_index++;
570
}
571
else
572
{
573
valuesReceived[comma_index] = valuesReceived[comma_index] * 10 + (serial_data[k] - 48);
574
}
575
}
576
577
accOffset[0] = valuesReceived[0] - 2000;
578
accOffset[1] = valuesReceived[1] - 2000;
579
accOffset[2] = valuesReceived[2] - 2000;
580
581
serial_index = 0;
582
string_started = 0;
583
584
SaveAccelData();
585
}
586
587
// Retrieve settings
588
else
if
(serial_data[serial_index-4] ==
'G'
&&
589
serial_data[serial_index-3] ==
'S'
&&
590
serial_data[serial_index-2] ==
'E'
&&
591
serial_data[serial_index-1] ==
'T'
)
592
{
593
// Get Settings. Scale our local values to
594
// real-world values usable on the PC side.
595
//
596
Serial
.print(
"$SET$"
);
// something recognizable in the stream
597
598
Serial
.print(tiltRollBeta * 100);
599
Serial
.print(
","
);
600
Serial
.print(panBeta * 100);
601
Serial
.print(
","
);
602
Serial
.print(gyroWeightTiltRoll * 100);
603
Serial
.print(
","
);
604
Serial
.print(GyroWeightPan * 100);
605
Serial
.print(
","
);
606
Serial
.print(tiltFactor * 10);
607
Serial
.print(
","
);
608
Serial
.print(panFactor * 10);
609
Serial
.print(
","
);
610
Serial
.print(rollFactor * 10);
611
Serial
.print(
","
);
612
Serial
.print(servoReverseMask);
613
Serial
.print(
","
);
614
Serial
.print(servoPanCenter);
615
Serial
.print(
","
);
616
Serial
.print(panMinPulse);
617
Serial
.print(
","
);
618
Serial
.print(panMaxPulse);
619
Serial
.print(
","
);
620
Serial
.print(servoTiltCenter);
621
Serial
.print(
","
);
622
Serial
.print(tiltMinPulse);
623
Serial
.print(
","
);
624
Serial
.print(tiltMaxPulse);
625
Serial
.print(
","
);
626
Serial
.print(servoRollCenter);
627
Serial
.print(
","
);
628
Serial
.print(rollMinPulse);
629
Serial
.print(
","
);
630
Serial
.print(rollMaxPulse);
631
Serial
.print(
","
);
632
Serial
.print(htChannels[0]);
633
Serial
.print(
","
);
634
Serial
.print(htChannels[1]);
635
Serial
.print(
","
);
636
Serial
.println(htChannels[2]);
637
638
Serial
.println(
"Settings Retrieved!"
);
639
640
serial_index = 0;
641
string_started = 0;
642
}
643
else
if
(serial_index > 100)
644
{
645
// If more than 100 bytes have been received, the string is not valid.
646
// Reset and "try again" (wait for $ to indicate start of new string).
647
serial_index = 0;
648
string_started = 0;
649
}
650
}
651
else
if
(
Serial
.read() ==
'$'
)
652
{
653
string_started = 1;
654
}
655
}
// serial port input
656
657
// if "read_sensors" flag is set high, read sensors and update
658
if
(read_sensors == 1 && ht_paused == 0)
659
{
660
UpdateSensors();
661
GyroCalc();
662
AccelCalc();
663
MagCalc();
664
FilterSensorData();
665
666
// Only output this data every X frames.
667
if
(frameNumber++ >= SERIAL_OUTPUT_FRAME_INTERVAL)
668
{
669
if
(outputTrack == 1)
670
{
671
trackerOutput();
672
}
673
else
if
(outputMagAcc == 1)
674
{
675
calMagAccOutput();
676
}
677
else
if
(outputMag == 1)
678
{
679
calMagOutput();
680
}
681
else
if
(outputAcc == 1)
682
{
683
calAccOutput();
684
}
685
frameNumber = 0;
686
}
687
688
// Will first update read_sensors when everything is done.
689
read_sensors = 0;
690
}
691
}
692
693
//--------------------------------------------------------------------------------------
694
// Func: SaveSettings
695
// Desc: Saves device settings to EEPROM for retrieval at boot-up.
696
//--------------------------------------------------------------------------------------
697
void
SaveSettings()
698
{
699
EEPROM.write(1, (unsigned
char
)(tiltRollBeta * 100));
700
EEPROM.write(2, (unsigned
char
)(panBeta * 100));
701
EEPROM.write(3, (unsigned
char
)(gyroWeightTiltRoll * 100));
702
EEPROM.write(4, (unsigned
char
)(GyroWeightPan * 100));
703
704
EEPROM.write(5, (unsigned
char
)servoReverseMask);
705
706
// 6 unused
707
708
EEPROM.write(7, (unsigned
char
)servoPanCenter);
709
EEPROM.write(8, (unsigned
char
)(servoPanCenter >> 8));
710
711
EEPROM.write(9, (unsigned
char
)(tiltFactor * 10));
712
EEPROM.write(10, (
int
)((tiltFactor * 10)) >> 8);
713
714
EEPROM.write(11, (unsigned
char
) (panFactor * 10));
715
EEPROM.write(12, (
int
)((panFactor * 10)) >> 8);
716
717
EEPROM.write(13, (unsigned
char
) (rollFactor * 10));
718
EEPROM.write(14, (
int
)((rollFactor * 10)) >> 8);
719
720
// 15 unused
721
722
EEPROM.write(16, (unsigned
char
)servoTiltCenter);
723
EEPROM.write(17, (unsigned
char
)(servoTiltCenter >> 8));
724
725
EEPROM.write(18, (unsigned
char
)servoRollCenter);
726
EEPROM.write(19, (unsigned
char
)(servoRollCenter >> 8));
727
728
729
EEPROM.write(20, (unsigned
char
)panMaxPulse);
730
EEPROM.write(21, (unsigned
char
)(panMaxPulse >> 8));
731
732
EEPROM.write(22, (unsigned
char
)panMinPulse);
733
EEPROM.write(23, (unsigned
char
)(panMinPulse >> 8));
734
735
EEPROM.write(24, (unsigned
char
)tiltMaxPulse);
736
EEPROM.write(25, (unsigned
char
)(tiltMaxPulse >> 8));
737
738
EEPROM.write(26, (unsigned
char
)tiltMinPulse);
739
EEPROM.write(27, (unsigned
char
)(tiltMinPulse >> 8));
740
741
EEPROM.write(28, (unsigned
char
)rollMaxPulse);
742
EEPROM.write(29, (unsigned
char
)(rollMaxPulse >> 8));
743
744
EEPROM.write(30, (unsigned
char
)rollMinPulse);
745
EEPROM.write(31, (unsigned
char
)(rollMinPulse >> 8));
746
747
EEPROM.write(32, (unsigned
char
)htChannels[0]);
748
EEPROM.write(33, (unsigned
char
)htChannels[1]);
749
EEPROM.write(34, (unsigned
char
)htChannels[2]);
750
751
// Saving gyro calibration values
752
int
temp = (
int
)(gyroOff[0] + 500.5);
753
EEPROM.write(35, (unsigned
char
)temp);
754
EEPROM.write(36, (unsigned
char
)(temp >> 8));
755
756
temp = (
int
)(gyroOff[1] + 500.5);
757
EEPROM.write(37, (unsigned
char
)temp);
758
EEPROM.write(38, (unsigned
char
)(temp >> 8));
759
760
temp = (
int
)(gyroOff[2] + 500.5);
761
EEPROM.write(39, (unsigned
char
)temp);
762
EEPROM.write(40, (unsigned
char
)(temp >> 8));
763
764
// Mark the memory to indicate that it has been
765
// written. Used to determine if board is newly flashed
766
// or not.
767
EEPROM.write(0,8);
768
769
Serial
.println(
"Settings saved!"
);
770
}
771
772
//--------------------------------------------------------------------------------------
773
// Func: GetSettings
774
// Desc: Retrieves device settings from EEPROM.
775
//--------------------------------------------------------------------------------------
776
void
GetSettings()
777
{
778
tiltRollBeta = (
float
)EEPROM.read(1) / 100;
779
panBeta = (
float
)EEPROM.read(2) / 100;
780
gyroWeightTiltRoll = (
float
)EEPROM.read(3) / 100;
781
GyroWeightPan = (
float
)EEPROM.read(4) / 100;
782
783
tiltInverse = 1;
784
rollInverse = 1;
785
panInverse = 1;
786
787
unsigned
char
temp = EEPROM.read(5);
788
if
( temp & HT_TILT_REVERSE_BIT )
789
{
790
tiltInverse = -1;
791
}
792
if
( temp & HT_ROLL_REVERSE_BIT )
793
{
794
rollInverse = -1;
795
}
796
if
( temp & HT_PAN_REVERSE_BIT )
797
{
798
panInverse = -1;
799
}
800
801
// 6 unused
802
803
servoPanCenter = EEPROM.read(7) + (EEPROM.read(8) << 8);
804
tiltFactor = (
float
)(EEPROM.read(9) + (EEPROM.read(10) << 8)) / 10;
805
panFactor = (
float
)(EEPROM.read(11) + (EEPROM.read(12) << 8)) / 10;
806
rollFactor = (
float
)(EEPROM.read(13) + (EEPROM.read(14) << 8)) / 10;
807
808
// 15 unused
809
810
servoTiltCenter = EEPROM.read(16) + (EEPROM.read(17) << 8);
811
servoRollCenter = EEPROM.read(18) + (EEPROM.read(19) << 8);
812
813
panMaxPulse = EEPROM.read(20) + (EEPROM.read(21) << 8);
814
panMinPulse = EEPROM.read(22) + (EEPROM.read(23) << 8);
815
816
tiltMaxPulse = EEPROM.read(24) + (EEPROM.read(25) << 8);
817
tiltMinPulse = EEPROM.read(26) + (EEPROM.read(27) << 8);
818
819
rollMaxPulse = EEPROM.read(28) + (EEPROM.read(29) << 8);
820
rollMinPulse = EEPROM.read(30) + (EEPROM.read(31) << 8);
821
822
htChannels[0] = EEPROM.read(32);
823
htChannels[1] = EEPROM.read(33);
824
htChannels[2] = EEPROM.read(34);
825
826
gyroOff[0] = EEPROM.read(35) + (EEPROM.read(36) << 8) - 500;
827
gyroOff[1] = EEPROM.read(37) + (EEPROM.read(38) << 8) - 500;
828
gyroOff[2] = EEPROM.read(39) + (EEPROM.read(40) << 8) - 500;
829
830
magOffset[0] = EEPROM.read(200) + (EEPROM.read(201) << 8) - 2000;
831
magOffset[1] = EEPROM.read(202) + (EEPROM.read(203) << 8) - 2000;
832
magOffset[2] = EEPROM.read(204) + (EEPROM.read(205) << 8) - 2000;
833
834
accOffset[0] = EEPROM.read(206) + (EEPROM.read(207) << 8) - 2000;
835
accOffset[1] = EEPROM.read(208) + (EEPROM.read(209) << 8) - 2000;
836
accOffset[2] = EEPROM.read(210) + (EEPROM.read(211) << 8) - 2000;
837
838
839
#if (DEBUG)
840
DebugOutput();
841
#endif
842
}
843
844
//--------------------------------------------------------------------------------------
845
// Func: SaveMagData
846
// Desc: Stores magnetometer calibration info to EEPROM.
847
//--------------------------------------------------------------------------------------
848
void
SaveMagData()
849
{
850
int
temp = (
int
)(magOffset[0] + 2000);
851
EEPROM.write(200, (unsigned
char
)temp);
852
EEPROM.write(201, (unsigned
char
)(temp >> 8));
853
854
temp = (
int
)(magOffset[1] + 2000);
855
EEPROM.write(202, (unsigned
char
)temp);
856
EEPROM.write(203, (unsigned
char
)(temp >> 8));
857
858
temp = (
int
)(magOffset[2] + 2000);
859
EEPROM.write(204, (unsigned
char
)temp);
860
EEPROM.write(205, (unsigned
char
)(temp >> 8));
861
862
Serial
.println(
"Mag offset saved!"
);
863
Serial
.print(magOffset[0]);
864
Serial
.print(
", "
);
865
Serial
.print(magOffset[1]);
866
Serial
.print(
", "
);
867
Serial
.println(magOffset[2]);
868
}
869
870
//--------------------------------------------------------------------------------------
871
// Func: SaveAccelData
872
// Desc: Stores accelerometer calibration data to EEPOM.
873
//--------------------------------------------------------------------------------------
874
void
SaveAccelData()
875
{
876
int
temp = (
int
)(accOffset[0] + 2000);
877
EEPROM.write(206, (unsigned
char
)temp);
878
EEPROM.write(207, (unsigned
char
)(temp >> 8));
879
880
temp = (
int
)(accOffset[1] + 2000);
881
EEPROM.write(208, (unsigned
char
)temp);
882
EEPROM.write(209, (unsigned
char
)(temp >> 8));
883
884
temp = (
int
)(accOffset[2] + 2000);
885
EEPROM.write(210, (unsigned
char
)temp);
886
EEPROM.write(211, (unsigned
char
)(temp >> 8));
887
888
Serial
.println(
"Acc offset saved!"
);
889
Serial
.print(accOffset[0]);
890
Serial
.print(
","
);
891
Serial
.print(accOffset[1]);
892
Serial
.print(
","
);
893
Serial
.println(accOffset[2]);
894
}
895
896
//--------------------------------------------------------------------------------------
897
// Func: DebugOutput
898
// Desc: Outputs useful device/debug information to the serial port.
899
//--------------------------------------------------------------------------------------
900
void
DebugOutput()
901
{
902
Serial
.println();
903
Serial
.println();
904
Serial
.println();
905
Serial
.println(
"------ Debug info------"
);
906
907
Serial
.print(
"FW Version: "
);
908
Serial
.println(FIRMWARE_VERSION_FLOAT, 2);
909
910
Serial
.print(
"tiltRollBeta: "
);
911
Serial
.println(tiltRollBeta);
912
913
Serial
.print(
"panBeta: "
);
914
Serial
.println(panBeta);
915
916
Serial
.print(
"gyroWeightTiltRoll: "
);
917
Serial
.println(gyroWeightTiltRoll);
918
919
Serial
.print(
"GyroWeightPan: "
);
920
Serial
.println(GyroWeightPan);
921
922
Serial
.print(
"servoPanCenter: "
);
923
Serial
.println(servoPanCenter);
924
925
Serial
.print(
"servoTiltCenter: "
);
926
Serial
.println(servoTiltCenter);
927
928
Serial
.print(
"servoRollCenter: "
);
929
Serial
.println(servoRollCenter);
930
931
Serial
.print(
"tiltFactor: "
);
932
Serial
.println(tiltFactor);
933
934
Serial
.print(
"panFactor: "
);
935
Serial
.println(panFactor);
936
937
Serial
.print(
"Gyro offset stored "
);
938
Serial
.print(gyroOff[0]);
939
Serial
.print(
","
);
940
Serial
.print(gyroOff[1]);
941
Serial
.print(
","
);
942
Serial
.println(gyroOff[2]);
943
944
Serial
.print(
"Mag offset stored "
);
945
Serial
.print(magOffset[0]);
946
Serial
.print(
","
);
947
Serial
.print(magOffset[1]);
948
Serial
.print(
","
);
949
Serial
.println(magOffset[2]);
950
951
Serial
.print(
"Acc offset stored "
);
952
Serial
.print(accOffset[0]);
953
Serial
.print(
","
);
954
Serial
.print(accOffset[1]);
955
Serial
.print(
","
);
956
Serial
.println(accOffset[2]);
957
958
SensorInfoPrint();
959
}
О блин аж в 3 посте придумал чё хотел.
Ну будем считать что с тз разобрались. Куда копать?
Возможность есть. Копать до обеда в сторону дуба.
Отлично! Осталось услышать советы по выбору лопаты и методике рытья.
Лопата в виде карандаша , ковырять на листе. Схему соединений. А потом уже ковырять скеч.
не понял. а что надо то? у кого то, у этого другое. а мне надо это. что это?
не понял. а что надо то? у кого то, у этого другое. а мне надо это. что это?
Тсссс он сам не знает точно.
сеанс телепатии. на голове цифровой гироскоп. с него через ардуину идет 3 сигнала на сервы, которые позиционируют что то, наверно камеру в точности как голова. так?
Сори если не достаточно точно расписал, вроде старался максимально подробно.
Все верно, это устройство управления камерой на р/у самолете поворотом головы. По первой ссылке есть видюха как это должно происходить. Для управления достаточно двух сервоприводов. Проблема в том что в первоначальном варианте эти сигналы загоняются в один РРМ поток и чтобы их выцепить нужна дорогая аппаратура р/у. Моя идея заключается в том чтобы сделать по аналогии с устройством из второй ссылки. Т.е. разнести каналы по разным выходам ардуины чтобы соединить с "крутилками" на аппаратуре р/у, отвечающими за поворот каждой отдельной сервы.
не понял. как соеденить с крутилками?
гироскоп - ардуина - сервы которые управляют джойстиками на аппаратуре радиоуправления?
странновато конечно. но сделать легко, тебе в том числе. купи сервы ардуину и гироскоп (выбирай самый распрастраненный, чтобы было много примеров) как будет железо научишься. примеры по сервам для начал в помощь
странновато конечно. но сделать легко, тебе в том числе. купи сервы ардуину и гироскоп (выбирай самый распрастраненный, чтобы было много примеров) как будет железо научишься. примеры по сервам для начал в помощь
Ты забыл про второе радио купить. И ардуин нужно 2.
не. зачем. приемники радиоаппаратуры обычно многоканальные, и остаются свободные выходы. на них повесит сервы для камеры и все
только так издеваться на хорошей аппаратурой, а она должна быть хорошая, в дешевых не будет скорее всего 2 свободных канала и 2 свободных джойстика (ну или один с 2 осями)
лучше камерой управлять отдельно своим радиоканалом и не мучать аппаратуру
не понял. как соеденить с крутилками?
гироскоп - ардуина - сервы которые управляют джойстиками на аппаратуре радиоуправления?
Не, немного не так, хотя тоже вариант. По первоначальной задумке выход с ардуины подключается вместо крутилки. Именно так и реализовано в "переключателе режимов". Но в крайнем случае если сделать согласно предложенному Вами варианту, я просто сварганю шестеренчатую передачу с сервы на крутилку.
Железяки все я уже собрал и ардуину зашил авторским скетчем. Все работает, судя по показаниям (графики в проге калибровки платы гироскопов меняются в зависимости от пространственного положения самой платы), но мне от этого не легче.
Каналов в аппаратуре шесть. Четыре-управление самиком, остальные два-резерв. На резервные каналы вынесены отдельные потенциометры - "крутилки". Приемник тоже шестиканальный
а каким авторским скетчем? было же 2 автора и 2 кода
Я имел ввиду скетч, который собирает оба канала в один поток. Скетч из "переключателя" это просто пример как должно быть реализовано схематически.
вот нельзя сразу написать или все надо вытягивать из тебя клещами? собрал железку говоришь. а что ты собрал?
а то сейчас можно предложить вариант и все продумать, а ты потом "у меня железка собрана, надо с ней сделать" и все коту под хвост
Я пытаюсь представить как люди типа тс пишут программы. Они словами то расказать не могут внятно.
Так а чо толку что я ее собрал? Ну да, собрал. Собрал согласно выложенным материалам. Ну да, зашил, ну да, все заработало, но заработало с закосом под другую аппаратуру, мне то это пользы не добавило. По крайней мере убедился в исправности комплектующих. Где тут преступление? Если б все нормально заработало разве стал бы я эту писанину разводить?
понятно. паять умеешь? мультиметр есть?
Да, да.
замерь напряжение между крайним правым и крайним левым выводом у джойстки чтобы знать какое напряжение опорное
подцепись между землей и средним джойстика и замерь напряжение в середине, крайнем левом и крайнем правом положении джойстика
выбери любых 2 пина с шимом. с ним фильтр. с фильтра на вход платы. дальше калибровать
замерь напряжение между крайним правым и крайним левым выводом у джойстки чтобы знать какое напряжение опорное
3.31B
подцепись между землей и средним джойстика и замерь напряжение в середине, крайнем левом и крайнем правом положении джойстика
меняется от нуля до 3.32. по центру 1.7
выбери любых 2 пина с шимом. с ним фильтр. с фильтра на вход платы. дальше калибровать
ну и отлично. фильтр резистор + конденсатор. считать лень. желательно иметь осциллограф
например резистор 2к + конденсатор 1мкф.
подбирать надо только номиналы. а точнее считать
далее играясь с шимом получить на выходе напряжение 3,32В (к пульту не подключать)
подкюлючить к пульту, напряжение должно немного упасть. скорректировать код
это значение шима не превышать
далее найти шим чтобы на выходе было 1,7В
постоить график по 3 точкам. 0В 1,7 и 3,32 и посмотреть линейность едениц шима