Skip to content

Commit 2eaa35b

Browse files
authored
Add files via upload
1 parent 031f918 commit 2eaa35b

File tree

9 files changed

+271
-279
lines changed

9 files changed

+271
-279
lines changed

PwmTransceiver.cpp

Lines changed: 90 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,108 @@
55
J1850-PWM-Transceiver-Library
66
*/
77

8-
#include <Arduino.h>
9-
#include "avr/interrupt.h"
108
#include <PwmTransceiver.h>
119

10+
volatile uint8_t _TX_PIN;
11+
volatile uint8_t _RX_PIN;
12+
volatile uint8_t _EN_PIN;
13+
volatile uint8_t _MODE_PIN;
14+
volatile uint32_t _BITRATE;
15+
volatile uint32_t _BIT_TIME;
16+
volatile uint32_t _HALF_BIT_TIME;
17+
volatile uint32_t _ONE_THIRD_BIT_TIME;
18+
volatile uint32_t _TWO_THIRD_BIT_TIME;
19+
volatile bool _high_speed = false;
20+
volatile char _RX_BUFFER[BUFFER_SIZE];
21+
volatile uint16_t _BUFFER_INDEX = 0;
22+
volatile uint32_t _timeOut = 500; // uS
23+
volatile unsigned long timeOldMicros;
24+
volatile unsigned long timeOldMillis = 0;
25+
volatile int _count = 7;
26+
volatile char _rx_char = 0x00;
27+
volatile bool _logic = true; // 1: Direct; 0: Inverse
28+
29+
void isrPwmDecoder()
30+
{
31+
if (digitalReadFast(_RX_PIN)==_logic)
32+
{
33+
timeOldMicros = micros();
34+
timeOldMillis = millis();
35+
}
36+
else
37+
{
38+
bool bit = micros() > timeOldMicros + _HALF_BIT_TIME;
39+
_rx_char ^= (-bit ^ _rx_char) & (1 << _count);
40+
//Serial.print(bit);
41+
if (_count > 0) _count--;
42+
else {
43+
_count = 7;
44+
_RX_BUFFER[_BUFFER_INDEX] = _rx_char;
45+
_BUFFER_INDEX++;
46+
_rx_char = 0x00;
47+
}
48+
}
49+
}
50+
51+
/*
52+
void isrPwmDecoder()
53+
{
54+
timeOldMicros = micros();
55+
while (digitalReadFast(_RX_PIN) == _logic);
56+
bool bit = (micros() - timeOldMicros) > _HALF_BIT_TIME;
57+
_rx_char ^= (-bit ^ _rx_char) & (1 << _count);
58+
if (_count > 0) _count--;
59+
else {
60+
_count = 7;
61+
_RX_BUFFER[_BUFFER_INDEX] = _rx_char;
62+
_BUFFER_INDEX++;
63+
_rx_char = 0x00;
64+
}
65+
timeOldMillis = millis();
66+
}
67+
*/
1268
PwmTransceiver::PwmTransceiver(uint8_t RX_PIN, uint8_t TX_PIN)
1369
{
1470
_RX_PIN = RX_PIN;
15-
pinMode(_RX_PIN, INPUT);
71+
pinModeFast(_RX_PIN, INPUT);
1672
_TX_PIN = TX_PIN;
17-
pinMode(_TX_PIN, OUTPUT);
73+
pinModeFast(_TX_PIN, OUTPUT);
1874
}
1975

2076
PwmTransceiver::PwmTransceiver(uint8_t RX_PIN, uint8_t TX_PIN, uint8_t MODE_PIN, uint8_t EN_PIN)
2177
{
2278
_RX_PIN = RX_PIN;
23-
pinMode(_RX_PIN, INPUT);
79+
pinModeFast(_RX_PIN, INPUT);
2480
_TX_PIN = TX_PIN;
25-
pinMode(_TX_PIN, OUTPUT);
81+
pinModeFast(_TX_PIN, OUTPUT);
2682
_MODE_PIN = MODE_PIN;
27-
pinMode(_MODE_PIN, OUTPUT);
83+
pinModeFast(_MODE_PIN, OUTPUT);
2884
_EN_PIN = EN_PIN;
29-
pinMode(_EN_PIN, OUTPUT);
85+
pinModeFast(_EN_PIN, OUTPUT);
3086
}
3187

3288
void PwmTransceiver::setRxPin(uint8_t RX_PIN)
3389
{
3490
_RX_PIN = RX_PIN;
35-
pinMode(_RX_PIN, INPUT);
91+
pinModeFast(_RX_PIN, INPUT);
3692
}
3793

3894
void PwmTransceiver::setTxPin(uint8_t TX_PIN)
3995
{
4096
_TX_PIN = TX_PIN;
41-
pinMode(_TX_PIN, OUTPUT);
97+
pinModeFast(_TX_PIN, OUTPUT);
4298
}
4399

44100
void PwmTransceiver::setEnablePin(uint8_t EN_PIN)
45101
{
46102
_EN_PIN = EN_PIN;
47-
pinMode(_EN_PIN, OUTPUT);
103+
pinModeFast(_EN_PIN, OUTPUT);
48104
}
49105

50106
void PwmTransceiver::setTxRxModePin(uint8_t MODE_PIN)
51107
{
52108
_MODE_PIN = MODE_PIN;
53-
pinMode(_MODE_PIN, OUTPUT);
109+
pinModeFast(_MODE_PIN, OUTPUT);
54110
}
55111

56112
void PwmTransceiver::setLogic(bool logic)
@@ -83,32 +139,32 @@ void PwmTransceiver::begin(uint32_t BITRATE)
83139
_HALF_BIT_TIME = _BIT_TIME / 2;
84140
_ONE_THIRD_BIT_TIME = _BIT_TIME / 3;
85141
_TWO_THIRD_BIT_TIME = _BIT_TIME * 2 / 3;
86-
if (_logic) attachInterrupt(digitalPinToInterrupt(_RX_PIN), isrPwmDecoder, RISING);
87-
else attachInterrupt(digitalPinToInterrupt(_RX_PIN), isrPwmDecoder, FALLING);
88-
flagDecoder = false;
142+
enableInterrupt(_RX_PIN, isrPwmDecoder, CHANGE);
143+
//if (_logic) enableInterrupt(_RX_PIN, isrPwmDecoder, RISING);
144+
//else enableInterrupt(_RX_PIN, isrPwmDecoder, FALLING);
89145
}
90146

91147
void PwmTransceiver::powerDown()
92148
{
93-
digitalWrite(_EN_PIN, LOW);
149+
digitalWriteFast(_EN_PIN, LOW);
94150
delay(15);
95151
}
96152

97153
void PwmTransceiver::powerUp()
98154
{
99-
digitalWrite(_EN_PIN, HIGH);
155+
digitalWriteFast(_EN_PIN, HIGH);
100156
delay(15);
101157
}
102158

103159
void PwmTransceiver::enableTxMode()
104160
{
105-
digitalWrite(_MODE_PIN, HIGH);
161+
digitalWriteFast(_MODE_PIN, HIGH);
106162
delayMicroseconds(500);
107163
}
108164

109165
void PwmTransceiver::enableRxMode()
110166
{
111-
digitalWrite(_MODE_PIN, LOW);
167+
digitalWriteFast(_MODE_PIN, LOW);
112168
delayMicroseconds(500);
113169
}
114170

@@ -119,12 +175,12 @@ void PwmTransceiver::println(String str)
119175
}
120176

121177
void PwmTransceiver::print(String str)
122-
{
178+
{
123179
uint16_t size = str.length() + 1;
124180
char txt[size];
125181
str.toCharArray(txt, size);
126182
uint16_t i;
127-
for (i = 0; i < size; i++)
183+
for (i = 0; i < size - 1; i++)
128184
{
129185
PwmTransceiver::print(txt[i]);
130186
}
@@ -166,17 +222,17 @@ void PwmTransceiver::send(bool b)
166222
if (b)
167223
{
168224
/* Send 66% HIGH, 33% LOW */
169-
digitalWrite(_TX_PIN, HIGH);
225+
digitalWriteFast(_TX_PIN, HIGH);
170226
delayMicroseconds(_TWO_THIRD_BIT_TIME);
171-
digitalWrite(_TX_PIN, LOW);
227+
digitalWriteFast(_TX_PIN, LOW);
172228
delayMicroseconds(_ONE_THIRD_BIT_TIME);
173229
}
174230
else
175231
{
176232
/* Send 33% HIGH, 66% LOW */
177-
digitalWrite(_TX_PIN, HIGH);
233+
digitalWriteFast(_TX_PIN, HIGH);
178234
delayMicroseconds(_ONE_THIRD_BIT_TIME);
179-
digitalWrite(_TX_PIN, LOW);
235+
digitalWriteFast(_TX_PIN, LOW);
180236
delayMicroseconds(_TWO_THIRD_BIT_TIME);
181237
}
182238
}
@@ -185,68 +241,22 @@ void PwmTransceiver::send(bool b)
185241
if (b)
186242
{
187243
/* Send 66% HIGH, 33% LOW */
188-
digitalWrite(_TX_PIN, HIGH);
244+
digitalWriteFast(_TX_PIN, HIGH);
189245
delay(_TWO_THIRD_BIT_TIME);
190-
digitalWrite(_TX_PIN, LOW);
246+
digitalWriteFast(_TX_PIN, LOW);
191247
delay(_ONE_THIRD_BIT_TIME);
192248
}
193249
else
194250
{
195251
/* Send 33% HIGH, 66% LOW */
196-
digitalWrite(_TX_PIN, HIGH);
252+
digitalWriteFast(_TX_PIN, HIGH);
197253
delay(_ONE_THIRD_BIT_TIME);
198-
digitalWrite(_TX_PIN, LOW);
254+
digitalWriteFast(_TX_PIN, LOW);
199255
delay(_TWO_THIRD_BIT_TIME);
200256
}
201257
}
202258
}
203259

204-
static void PwmTransceiver::isrPwmDecoder()
205-
{
206-
timeOld = millis();
207-
flagDecoder = true;
208-
}
209-
210-
void PwmTransceiver::receive()
211-
{
212-
if (flagDecoder)
213-
{
214-
flagDecoder = false;
215-
216-
if (_high_speed)
217-
{
218-
delayMicroseconds(_HALF_BIT_TIME);
219-
}
220-
else
221-
{
222-
delay(_HALF_BIT_TIME);
223-
}
224-
225-
//https://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit
226-
227-
if (_logic)
228-
{
229-
_rx_char ^= (-digitalRead(_RX_PIN) ^ _rx_char) & (1 << _count);
230-
}
231-
else
232-
{
233-
_rx_char ^= (-(!digitalRead(_RX_PIN)) ^ _rx_char) & (1 << _count);
234-
}
235-
236-
if (_count > 0)
237-
{
238-
_count--;
239-
}
240-
else
241-
{
242-
_count = 7;
243-
_RX_BUFFER[_BUFFER_INDEX] = _rx_char;
244-
_BUFFER_INDEX++;
245-
_rx_char = 0x00;
246-
}
247-
}
248-
}
249-
250260
bool PwmTransceiver::isReceiving()
251261
{
252262
if (_BUFFER_INDEX > BUFFER_SIZE - 1)
@@ -255,22 +265,19 @@ bool PwmTransceiver::isReceiving()
255265
_BUFFER_INDEX = BUFFER_SIZE - 1;
256266
return false;
257267
}
258-
// Check if millis has resetted
259-
if (millis() < timeOld) timeOld = millis();
260268

261269
// Check the lost of synchronicity
262-
if (millis() > (timeOld + _timeOut))
270+
271+
if (millis() > timeOldMillis + _timeOut)
263272
{
264273
_rx_char = 0x00;
265274
_count = 7;
266275
return false;
267276
}
268-
else
269-
{
270-
return true;
271-
}
277+
278+
return true;
272279
}
273-
280+
274281
bool PwmTransceiver::available()
275282
{
276283
return (_BUFFER_INDEX > 0);

PwmTransceiver.h

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,19 @@
55
J1850-Arduino-Transceiver-Library
66
*/
77

8+
#define LIBCALL_ENABLEINTERRUPT
9+
#include <stdint.h>
810
#include <Arduino.h>
9-
#include "avr/interrupt.h"
10-
11+
#include <avr/io.h>
12+
#include <avr/interrupt.h>
13+
#include <TimerOne.h>
14+
#include <digitalWriteFast.h>
15+
#define EI_ARDUINO_INTERRUPTED_PIN
16+
#include <EnableInterrupt.h>
1117
#define BUFFER_SIZE 64
1218

1319
class PwmTransceiver
1420
{
15-
16-
static volatile bool flagDecoder;
17-
static volatile unsigned long timeOld;
18-
19-
private:
20-
uint8_t _RX_PIN;
21-
uint8_t _TX_PIN;
22-
uint8_t _EN_PIN;
23-
uint8_t _MODE_PIN;
24-
uint32_t _BITRATE;
25-
uint32_t _BIT_TIME;
26-
uint32_t _HALF_BIT_TIME;
27-
uint32_t _ONE_THIRD_BIT_TIME;
28-
uint32_t _TWO_THIRD_BIT_TIME;
29-
bool _high_speed = false;
30-
bool _logic = true; // 1: Direct; 0: Inverse
31-
char _RX_BUFFER[BUFFER_SIZE];
32-
uint16_t _BUFFER_INDEX = 0;
33-
int _count = 7;
34-
35-
uint16_t _timeOut = 100; // mS
36-
char _rx_char = 0x00;
3721

3822
public:
3923
PwmTransceiver(uint8_t RX_PIN, uint8_t TX_PIN);
@@ -59,8 +43,6 @@ class PwmTransceiver
5943
void print(uint8_t n);
6044
void send (bool b);
6145

62-
static void isrPwmDecoder();
63-
void receive();
6446
bool isReceiving();
6547
bool available();
6648
String readString();
@@ -69,3 +51,9 @@ class PwmTransceiver
6951
byte CRC8(byte data[], byte len);
7052

7153
};
54+
/*
55+
extern volatile bool flagDecoder;
56+
extern volatile unsigned long timeOld;
57+
extern void isrPwmDecoder();
58+
extern void checkMicrosReset();
59+
*/

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ Arduino library which allow to communicate on J1850-PWM mode.
33
It works with wire, radio and laser transmissions.
44
You just have to choose your bit-rate (lower is better), tx and rx pins.
55
It doesn't have either a header nor a parity check. These functions could be implemented at a higher protocol layer.
6+
7+
Required libraries:
8+
1. DigitalWriteFast (Tested with version 1.0.0, Download: https://github.com/watterott/Arduino-Libs)
9+
2. EnableInterrupt (Tested with version 0.9.5, Download: https://github.com/GreyGnome/EnableInterrupt)
10+
611
This library has been tested with:
712
1. Wire connection between two Arduino
813
2. Radio connection (multipoint) with FSK modulation (and OOK too), module RTX-MID-868. Datasheet: https://goo.gl/UEv8ii

0 commit comments

Comments
 (0)