Skip to content

Commit 5a136cc

Browse files
committed
Added release: 0.9.2
1 parent ea1911d commit 5a136cc

File tree

3 files changed

+359
-31
lines changed

3 files changed

+359
-31
lines changed

.gitignore

+128-29
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,131 @@
1-
# Prerequisites
2-
*.d
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
35

4-
# Compiled Object files
5-
*.slo
6-
*.lo
7-
*.o
8-
*.obj
6+
# C extensions
7+
*.so
98

10-
# Precompiled Headers
11-
*.gch
12-
*.pch
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
mp4/
16+
eggs/
17+
.eggs/
18+
parts/
19+
sdist/
20+
var/
21+
wheels/
22+
pip-wheel-metadata/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
1328

14-
# Compiled Dynamic libraries
15-
*.so
16-
*.dylib
17-
*.dll
18-
19-
# Fortran module files
20-
*.mod
21-
*.smod
22-
23-
# Compiled Static libraries
24-
*.lai
25-
*.la
26-
*.a
27-
*.lib
28-
29-
# Executables
30-
*.exe
31-
*.out
32-
*.app
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
34+
# Installer logs
35+
pip-log.txt
36+
pip-delete-this-directory.txt
37+
38+
# Unit test / coverage reports
39+
htmlcov/
40+
.tox/
41+
.nox/
42+
.coverage
43+
.coverage.*
44+
.cache
45+
nosetests.xml
46+
coverage.xml
47+
*.cover
48+
*.py,cover
49+
.hypothesis/
50+
.pytest_cache/
51+
52+
# Translations
53+
*.mo
54+
*.pot
55+
56+
# Django stuff:
57+
*.log
58+
local_settings.py
59+
db.sqlite3
60+
db.sqlite3-journal
61+
62+
# Flask stuff:
63+
instance/
64+
.webassets-cache
65+
66+
# Scrapy stuff:
67+
.scrapy
68+
69+
# Sphinx documentation
70+
docs/_build/
71+
docs/build/
72+
73+
# PyCharm
74+
.idea/
75+
76+
# PyBuilder
77+
target/
78+
79+
# Jupyter Notebook
80+
.ipynb_checkpoints
81+
82+
# IPython
83+
profile_default/
84+
ipython_config.py
85+
86+
# pyenv
87+
.python-version
88+
89+
# pipenv
90+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
92+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
93+
# install all needed dependencies.
94+
#Pipfile.lock
95+
96+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
97+
__pypackages__/
98+
99+
# Celery stuff
100+
celerybeat-schedule
101+
celerybeat.pid
102+
103+
# SageMath parsed files
104+
*.sage.py
105+
106+
# Environments
107+
.env
108+
.venv
109+
env/
110+
venv/
111+
ENV/
112+
env.bak/
113+
venv.bak/
114+
115+
# Spyder project settings
116+
.spyderproject
117+
.spyproject
118+
119+
# Rope project settings
120+
.ropeproject
121+
122+
# mkdocs documentation
123+
/site
124+
125+
# mypy
126+
.mypy_cache/
127+
.dmypy.json
128+
dmypy.json
129+
130+
# Pyre type checker
131+
.pyre/

README.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,18 @@
1-
# arduino
2-
[C++] Arduino client
1+
# SERVO CAM - Arduino Client (C++)
2+
3+
## This repository is a part of SERVO CAM project.
4+
5+
![logo2](https://user-images.githubusercontent.com/129175238/228258366-c533475f-4e44-4717-a9ee-2ba5df2818e1.png)
6+
7+
Project website: https://servocam.org
8+
9+
Documentation (en): https://servo-cam.readthedocs.io/en/latest
10+
11+
GitHub: https://github.com/servo-cam
12+
13+
Release: **0.9.2** | 2023.03.27
14+
15+
------
16+
(c) 2023, servocam.org
17+
18+
MIT License

client/client.ino

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/*
2+
============================
3+
4+
SERVO CAM Arduino Client
5+
v 0.9.2 | 2023.03.22
6+
7+
(c) 2023, servocam.org
8+
https://servocam.org
9+
https://github.com/servo-cam
10+
info@servocam.org
11+
12+
============================
13+
*/
14+
15+
#include <Servo.h>
16+
17+
// --------- BEGIN CONFIG -----------
18+
19+
#define DEBUG false // debug mode (sends status to serial after every command)
20+
21+
#define PIN_SERVO_X 10 // servo X (horizontal) PWM pin
22+
#define PIN_SERVO_Y 11 // servo Y (vertical) PWM pin
23+
#define PIN_ACTION_1 2 // action #1 (A1) DIGITAL pin
24+
#define PIN_ACTION_2 4 // action #2 (A2) DIGITAL pin
25+
#define PIN_ACTION_3 7 // action #3 (A3) DIGITAL pin
26+
#define PIN_ACTION_4 8 // action #4 (B4) DIGITAL pin
27+
#define PIN_ACTION_5 12 // action #5 (B5) DIGITAL pin
28+
#define PIN_ACTION_6 13 // action #6 (B6) DIGITAL pin
29+
30+
#define SERVO_X_MIN 0 // servo X min angle
31+
#define SERVO_X_MAX 180 // servo X max angle
32+
#define SERVO_Y_MIN 0 // servo Y min angle
33+
#define SERVO_Y_MAX 180 // servo Y max angle
34+
35+
#define SERVO_X_LIMIT_MIN 0 // servo X min allowed movement angle
36+
#define SERVO_X_LIMIT_MAX 180 // servo X max allowed movement angle
37+
#define SERVO_Y_LIMIT_MIN 0 // servo Y min allowed movement angle
38+
#define SERVO_Y_LIMIT_MAX 180 // servo Y max allowed movement angle
39+
40+
#define SERVO_X_PULSE_MIN 771 // servo X min pulse
41+
#define SERVO_X_PULSE_MAX 2193 // servo X max pulse
42+
#define SERVO_Y_PULSE_MIN 771 // servo Y min pulse
43+
#define SERVO_Y_PULSE_MAX 2193 // servo Y max pulse
44+
45+
#define SERVO_X_INITIAL_ANGLE 90 // servo X start angle
46+
#define SERVO_Y_INITIAL_ANGLE 90 // servo Y start angle
47+
48+
#define SERIAL_TIMEOUT 4 // serial port timeout
49+
#define SERIAL_BAUD_RATE 9600 // serial port baud rate
50+
51+
// --------- END OF CONFIG -----------
52+
53+
54+
bool actions[6] = {}; // action states
55+
int pins[6] = {}; // action pins
56+
int counter = 0; // detected objects counter
57+
int x = 0; // servo X current angle
58+
int y = 0; // servo Y current angle
59+
60+
char *cmd[9]; // extracted commands
61+
char *ptr = NULL; // str cmd pointer
62+
63+
Servo servo_x; // servo X
64+
Servo servo_y; // servo Y
65+
String buffer; // serial data buffer
66+
67+
void setup()
68+
{
69+
Serial.begin(SERIAL_BAUD_RATE); // begin serial
70+
Serial.setTimeout(SERIAL_TIMEOUT); // set minimal timeout
71+
72+
// setup action pins
73+
pins[0] = PIN_ACTION_1; // action #1 (A1) pin
74+
pins[1] = PIN_ACTION_2; // action #2 (A2) pin
75+
pins[2] = PIN_ACTION_3; // action #3 (A3) pin
76+
pins[3] = PIN_ACTION_4; // action #4 (B4) pin
77+
pins[4] = PIN_ACTION_5; // action #5 (B5) pin
78+
pins[5] = PIN_ACTION_6; // action #6 (B6) pin
79+
80+
x = SERVO_X_INITIAL_ANGLE; // start servo X with default position
81+
y = SERVO_Y_INITIAL_ANGLE; // start servo Y with default position
82+
83+
// setup servo
84+
servo_x.write(x); // set initial servo X position
85+
servo_y.write(y); // set initial servo Y position
86+
servo_x.attach(PIN_SERVO_X, SERVO_X_PULSE_MIN, SERVO_X_PULSE_MAX); // attach servo X
87+
servo_y.attach(PIN_SERVO_Y, SERVO_Y_PULSE_MIN, SERVO_Y_PULSE_MAX); // attach servo Y
88+
89+
// initialize action pins with LOW state
90+
for (int i = 0; i < 6; i++) {
91+
pinMode(pins[i], OUTPUT); // set pin to OUTPUT mode
92+
actions[i] = false; // store disabled state
93+
digitalWrite(pins[i], LOW); // set state = LOW
94+
}
95+
}
96+
97+
// define status message here, must returns String
98+
String get_status() {
99+
return "RECV: " + buffer;
100+
}
101+
102+
void loop()
103+
{
104+
buffer = ""; // clear
105+
106+
// read serial buffer
107+
if (Serial.available() > 0) {
108+
buffer = Serial.readStringUntil('\n'); // \n must be the command terminator
109+
if (buffer == "\n" || buffer == "") {
110+
return; // abort if empty command
111+
}
112+
// send parsed status message if command == 0 received
113+
if (buffer == "0") {
114+
Serial.println(get_status() + ""); // <---------- STATUS SEND
115+
return;
116+
}
117+
} else {
118+
return; // abort if no command
119+
}
120+
121+
// parse buffer
122+
if (buffer.length() > 0) {
123+
byte index = 0;
124+
byte ary[buffer.length() + 1];
125+
buffer.toCharArray(ary, buffer.length() + 1);
126+
ptr = strtok(ary, ","); // command delimiter
127+
while (ptr != NULL) {
128+
cmd[index] = ptr;
129+
index++;
130+
ptr = strtok(NULL, ",");
131+
}
132+
133+
String tmp_cmd; // tmp string
134+
135+
// get servo positions
136+
if (index > 0) {
137+
tmp_cmd = String(cmd[0]); // servo X angle
138+
x = tmp_cmd.toInt(); // to integer
139+
}
140+
if (index > 1) {
141+
tmp_cmd = String(cmd[1]); // servo Y angle
142+
y = tmp_cmd.toInt(); // to integer
143+
}
144+
145+
// fix min/max angle
146+
if (x < SERVO_X_MIN) {
147+
x = SERVO_X_MIN;
148+
} else if (x > SERVO_X_MAX) {
149+
x = SERVO_X_MAX;
150+
}
151+
if (y < SERVO_Y_MIN) {
152+
y = SERVO_Y_MIN;
153+
} else if (y > SERVO_Y_MAX) {
154+
y = SERVO_Y_MAX;
155+
}
156+
157+
// fix min/max allowed movement angle
158+
if (x < SERVO_X_LIMIT_MIN) {
159+
x = SERVO_X_LIMIT_MIN;
160+
} else if (x > SERVO_X_LIMIT_MAX) {
161+
x = SERVO_X_LIMIT_MAX;
162+
}
163+
if (y < SERVO_Y_LIMIT_MIN) {
164+
y = SERVO_Y_LIMIT_MIN;
165+
} else if (y > SERVO_Y_LIMIT_MAX) {
166+
y = SERVO_Y_LIMIT_MAX;
167+
}
168+
169+
// move servo position
170+
servo_x.write(x); // move servo X
171+
servo_y.write(y); // move servo Y
172+
173+
// prepare rest of commands
174+
if (index > 2) {
175+
tmp_cmd = String(cmd[2]); // detected objects count
176+
if (tmp_cmd != "") {
177+
counter = tmp_cmd.toInt(); // to integer
178+
}
179+
}
180+
181+
// get action states
182+
for (int i = 0; i < 6; i++) {
183+
int j = i + 3;
184+
if (index > j) {
185+
tmp_cmd = String(cmd[j]);
186+
if (tmp_cmd != "") {
187+
actions[i] = (tmp_cmd.toInt() != 0); // to bool
188+
}
189+
}
190+
}
191+
192+
// apply action commands to pins
193+
for (int i = 0; i < 6; i++) {
194+
if (actions[i] == true) {
195+
digitalWrite(pins[i], HIGH); // enable action
196+
} else {
197+
digitalWrite(pins[i], LOW); // disable action
198+
}
199+
}
200+
}
201+
202+
// debug current position and command
203+
if (DEBUG == true) {
204+
Serial.print("CMD: ");
205+
Serial.println(buffer);
206+
Serial.print("POS: ");
207+
Serial.println(servo_x.read());
208+
Serial.println(servo_y.read());
209+
Serial.println();
210+
}
211+
212+
buffer = ""; // clear serial buffer
213+
}

0 commit comments

Comments
 (0)