Browse Source

add PPMDecoder fork

Thomas Buck 1 year ago
parent
commit
7177532a4a

+ 2
- 0
PPMDecoder/.gitattributes View File

1
+# Auto detect text files and perform LF normalization
2
+* text=auto

+ 21
- 0
PPMDecoder/LICENSE View File

1
+MIT License
2
+
3
+Copyright (c) 2020 Victor Glekler
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining a copy
6
+of this software and associated documentation files (the "Software"), to deal
7
+in the Software without restriction, including without limitation the rights
8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+copies of the Software, and to permit persons to whom the Software is
10
+furnished to do so, subject to the following conditions:
11
+
12
+The above copyright notice and this permission notice shall be included in all
13
+copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+SOFTWARE.

+ 56
- 0
PPMDecoder/README.md View File

1
+![PROJECT_PHOTO](https://github.com/VICLER/PPMDecoder/blob/master/ppm_img.PNG)
2
+
3
+<h3 align="center">PPM Decoder</h3>
4
+<p align="center">Arduino library for decoding PPM receiver signal</p>
5
+
6
+<!-- FEAUTURES -->
7
+## Features
8
+* Small size and easy to use
9
+* Non-Blocking operation using interrupts
10
+* Precise resolution of signal measuring (+- 0.5us)
11
+* Fast PPM to PWM (0-255) and Servo (544-2400us) conversion
12
+* Compatible with all ATMega328 16Mhz or 8Mhz Arduino boards
13
+
14
+## How to use
15
+```C++
16
+#include<PPM.h>                        // include library
17
+```
18
+```C++
19
+void begin(PPM_PIN, MAX_CHANNELS);     // init in void setup() // works only with pin 2(PD2) or pin 3(PD3)
20
+```
21
+```C++
22
+bool available();                     // returns 0 if there is no valid pulses from receiver
23
+```
24
+```C++
25
+uint16_t get(CHANNEL_NUMBER);            // get channel value in us
26
+```
27
+```C++
28
+uint8_t getPWM(CHANNEL_NUMBER);        // get pwm (0-255) channel value
29
+```
30
+```C++
31
+uint16_t getServo_us(CHANNEL_NUMBER);  // get Servo value (0-180)deg for using with Servo.writeMicroseconds() in range (544-2400)us
32
+```
33
+## Example
34
+```C++
35
+#include <PPM.h>
36
+
37
+#define CHANNELS 8    // max ppm channels
38
+#define PPM_PIN 2    // receiver ppm pin
39
+
40
+void setup() {
41
+  ppm.begin(PPM_PIN, CHANNELS);
42
+  Serial.begin(115200);
43
+}
44
+
45
+void loop() {
46
+
47
+  for (uint8_t i = 1; i <= CHANNELS; i++) // print all channel values
48
+  {
49
+    Serial.print(ppm.get(i));
50
+    Serial.print('\t');
51
+  }
52
+  Serial.println();
53
+  delay(10);
54
+
55
+}
56
+```

+ 24
- 0
PPMDecoder/examples/PPM-PWM-Servo/PPM-PWM-Servo.ino View File

1
+#include <PPM.h>
2
+#include <Servo.h>
3
+
4
+#define SERVO_PIN 9    // servo signal pin
5
+#define CHANNELS 8    // max ppm channels
6
+#define PPM_PIN 2    // receiver ppm pin
7
+#define LED 5       // led pin
8
+
9
+Servo servo;
10
+
11
+void setup() {
12
+  ppm.begin(PPM_PIN, CHANNELS);
13
+  servo.attach(SERVO_PIN);
14
+  pinMode(LED, OUTPUT);
15
+  Serial.begin(115200);
16
+}
17
+
18
+void loop() {
19
+
20
+  //servo.writeMicroseconds(ppm.getServo_us(1)); // write in range from (544 - 2400)us -> (0 - 180)deg. This is much faster than servo.write(0 - 180)
21
+  servo.writeMicroseconds(ppm.get(1));          // write raw PPM value to servo (1000 - 2000)us
22
+  analogWrite(LED, ppm.getPWM(3));             // write PWM value from channel 3 to led
23
+
24
+}

+ 22
- 0
PPMDecoder/examples/PPM_Read/PPM_Read.ino View File

1
+#include <PPM.h>
2
+
3
+#define CHANNELS 8   // max ppm channels
4
+#define PPM_PIN 2   // receiver ppm pin
5
+
6
+
7
+void setup() {
8
+  ppm.begin(PPM_PIN, CHANNELS);
9
+  Serial.begin(115200);
10
+}
11
+
12
+void loop() {
13
+  
14
+  for (uint8_t i = 1; i <= CHANNELS; i++) // print all channel values
15
+  {
16
+    Serial.print(ppm.get(i));
17
+    Serial.print('\t');
18
+  }
19
+  Serial.println();
20
+  delay(10);
21
+  
22
+}

+ 18
- 0
PPMDecoder/keywords.txt View File

1
+#######################################
2
+# Syntax Coloring Map PPM
3
+#######################################
4
+
5
+#######################################
6
+# Datatypes (KEYWORD1)
7
+#######################################
8
+
9
+ppm     KEYWORD1
10
+
11
+#######################################
12
+# Methods and Functions (KEYWORD2)
13
+#######################################
14
+
15
+begin       KEYWORD2
16
+get         KEYWORD2
17
+getPWM      KEYWORD2
18
+getServo_us KEYWORD2

+ 9
- 0
PPMDecoder/library.properties View File

1
+name=PPM
2
+version=1.2.0
3
+author=VICLER
4
+maintainer=VICLER
5
+sentence=Arduino library for Decoding PPM signal
6
+paragraph=For All PPM compatible receivers
7
+url=*
8
+category=Other
9
+architectures=*

BIN
PPMDecoder/ppm_img.PNG View File


+ 137
- 0
PPMDecoder/src/PPM.cpp View File

1
+/* Arduino library for decoding PPM receiver signal
2
+ *
3
+ * Copyright (c) 2020 Victor Glekler
4
+ *
5
+ * MIT License
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ * 
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ * 
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+#include "PPM.h"
26
+
27
+#include <avr/interrupt.h>
28
+#include <avr/io.h>
29
+
30
+PPM ppm;
31
+
32
+ISR(INT1_vect)
33
+{
34
+	//PORTB ^= (1 << PB5);
35
+	ppm.process();
36
+}
37
+
38
+ISR(TIMER2_OVF_vect)
39
+{
40
+	ppm.increment_ovf_count();
41
+}
42
+
43
+void PPM::begin(uint8_t max_channels = MAX_CHANNELS)
44
+{
45
+	//pinMode(inputPort, INPUT);
46
+	//pinMode(3, INPUT);
47
+	pinMode(3, INPUT_PULLUP);
48
+
49
+	//attachInterrupt(digitalPinToInterrupt(inputPort), ISR_PPM, FALLING);
50
+	cli();
51
+	// D3 / PD3 / INT1 for PPM input hard-coded
52
+	EICRA &= ~((1 << ISC11) | (1 << ISC10));
53
+	EICRA |= (1 << ISC11); // falling
54
+	//EICRA |= (1 << ISC11) | (1 << ISC10); // rising
55
+	EIMSK |= (1 << INT1);
56
+
57
+	_max_channels = max_channels;
58
+	for (uint8_t i = 0; i < MAX_CHANNELS; i++)
59
+		_channels[i] = 0;
60
+
61
+	_ovf_count = 0;
62
+	_micros_count = 0;
63
+
64
+	TCCR2B = (TCCR2B & 0b11111000) | (1 << CS21); 	// 8 prescaler
65
+	TIMSK2 |= 0b00000001;				 		   // enable TIMER2 overflow interrupt
66
+	TCCR2A &= 0b11111100;
67
+	TCCR2B &= 0b11110111;
68
+
69
+	sei();
70
+}
71
+
72
+uint32_t PPM::_micros()
73
+{
74
+	uint8_t SREG_old = SREG;
75
+	cli();
76
+	uint8_t tcnt2 = TCNT2;
77
+	bool flag_save = bitRead(TIFR2, 0);
78
+	if (flag_save)
79
+	{
80
+		tcnt2 = TCNT2;
81
+		_ovf_count++;
82
+		TIFR2 |= 0b00000001;
83
+	}
84
+	_micros_count = (_ovf_count << 8) | tcnt2 ;
85
+	SREG = SREG_old;
86
+#if (F_CPU == 16000000)
87
+	return _micros_count >> 1;
88
+#elif (F_CPU == 8000000)
89
+	return _micros_count;
90
+#endif
91
+}
92
+
93
+void PPM::increment_ovf_count()
94
+{
95
+	_ovf_count++;
96
+}
97
+
98
+void PPM::process()
99
+{
100
+	static uint8_t _channel_index = _max_channels;
101
+	static uint32_t _lastTime = 0, _currentTime = 0;
102
+
103
+	_currentTime = _micros();
104
+	int16_t pulse_us = _currentTime - _lastTime;
105
+	_lastTime = _currentTime;
106
+
107
+	if (pulse_us > 3000 && pulse_us < 12000) // sync
108
+	{
109
+		_channel_index = 0;
110
+		_available = true;
111
+		return;
112
+	}
113
+	else if (pulse_us > 12000)
114
+		_available = false;
115
+
116
+	if (_channel_index < _max_channels)
117
+		_channels[_channel_index++] = constrain(pulse_us, MIN_PULSE, MAX_PULSE);
118
+}
119
+
120
+uint16_t PPM::get(uint8_t channel)
121
+{
122
+	return (_channels[channel - 1]);
123
+}
124
+
125
+uint8_t PPM::getPWM(uint8_t channel)
126
+{
127
+	return (_channels[channel - 1] - MIN_PULSE) * 0.255f;
128
+}
129
+
130
+uint16_t PPM::getServo_us(uint8_t channel){
131
+	return ( (_channels[channel - 1] - 706.89655) * 1.856 ); // range 0 -> 180 using WriteMicroseconds
132
+}
133
+
134
+bool PPM::available()
135
+{
136
+	return _available;
137
+}

+ 60
- 0
PPMDecoder/src/PPM.h View File

1
+/* Arduino library for decoding PPM receiver signal
2
+ *
3
+ * Copyright (c) 2020 Victor Glekler
4
+ *
5
+ * MIT License
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ * 
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ * 
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+/**
25
+ * @file PPM.h
26
+ * @brief Base class for PPM Decoder
27
+ * @author Victor Glekler
28
+ * Contact: victor.glekler@gmail.com
29
+ * https://github.com/VICLER
30
+*/
31
+
32
+#pragma once
33
+
34
+#include "Arduino.h"
35
+
36
+#define MAX_CHANNELS 8 	  // the maximum channel number
37
+#define MIN_PULSE 1000	 // min valid impulse us
38
+#define MAX_PULSE 2000	// max valid impulse us
39
+
40
+class PPM
41
+{
42
+public:
43
+	void begin(uint8_t max_channels);
44
+	uint16_t get(uint8_t channel);
45
+	uint8_t getPWM(uint8_t channel);
46
+	uint16_t getServo_us(uint8_t channel);
47
+	void increment_ovf_count();
48
+	bool available();
49
+	void process();
50
+	
51
+private:
52
+	uint16_t _channels[MAX_CHANNELS];
53
+	volatile uint32_t _ovf_count;
54
+	uint8_t _max_channels;
55
+	uint32_t _micros_count;
56
+	uint32_t _micros();
57
+	bool _available;
58
+};
59
+
60
+extern PPM ppm;

Loading…
Cancel
Save