Skip to content

Commit 31c944a

Browse files
author
guoyongchao
committed
update encoder
1 parent 1cf94c4 commit 31c944a

File tree

10 files changed

+254
-49
lines changed

10 files changed

+254
-49
lines changed

encoder/ab_phase_encoder.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include "ab_phase_encoder.h"
2+
3+
#define DBG_SECTION_NAME "ab_phase_encoder"
4+
#define DBG_LEVEL DBG_LOG
5+
#include <rtdbg.h>
6+
7+
static const uint8_t AB_PHASE_ENCODER_TABLE[4] = {2, 0, 3, 1};
8+
9+
static void encoder_isr(void *args)
10+
{
11+
ab_phase_encoder_t enc_sub = (ab_phase_encoder_t)args;
12+
int val = rt_pin_read(enc_sub->pin_a) * 2 + rt_pin_read(enc_sub->pin_b);
13+
// rt_kprintf("val:%d\n", val);
14+
if (AB_PHASE_ENCODER_TABLE[enc_sub->last_value] == val)
15+
{
16+
enc_sub->enc.dir = ENCODER_DIR_FORWARD;
17+
enc_sub->enc.pulse_count++;
18+
}
19+
else
20+
{
21+
enc_sub->enc.dir = ENCODER_DIR_BACKWARD;
22+
enc_sub->enc.pulse_count--;
23+
}
24+
enc_sub->last_value = val;
25+
}
26+
27+
static rt_err_t ab_phase_encoder_enable(encoder_t enc)
28+
{
29+
RT_ASSERT(enc != RT_NULL);
30+
31+
ab_phase_encoder_t enc_sub = (ab_phase_encoder_t)enc;
32+
33+
// Attach interrupts
34+
rt_pin_mode(enc_sub->pin_a, PIN_MODE_INPUT);
35+
rt_pin_mode(enc_sub->pin_b, PIN_MODE_INPUT);
36+
rt_pin_attach_irq(enc_sub->pin_a, PIN_IRQ_MODE_RISING_FALLING, encoder_isr, enc_sub);
37+
rt_pin_attach_irq(enc_sub->pin_b, PIN_IRQ_MODE_RISING_FALLING, encoder_isr, enc_sub);
38+
enc_sub->last_value = rt_pin_read(enc_sub->pin_a) * 2 + rt_pin_read(enc_sub->pin_b);
39+
enc_sub->enc.last_time = rt_tick_get();
40+
rt_pin_irq_enable(enc_sub->pin_a, PIN_IRQ_ENABLE);
41+
rt_pin_irq_enable(enc_sub->pin_b, PIN_IRQ_ENABLE);
42+
43+
return RT_EOK;
44+
}
45+
46+
static rt_err_t ab_phase_encoder_disable(encoder_t enc)
47+
{
48+
RT_ASSERT(enc != RT_NULL);
49+
50+
ab_phase_encoder_t enc_sub = (ab_phase_encoder_t)enc;
51+
52+
rt_pin_irq_enable(enc_sub->pin_a, PIN_IRQ_DISABLE);
53+
rt_pin_irq_enable(enc_sub->pin_b, PIN_IRQ_DISABLE);
54+
55+
return RT_EOK;
56+
}
57+
58+
static rt_err_t ab_phase_encoder_destroy(encoder_t enc)
59+
{
60+
RT_ASSERT(enc != RT_NULL);
61+
62+
ab_phase_encoder_disable(enc);
63+
ab_phase_encoder_t enc_sub = (ab_phase_encoder_t)enc;
64+
rt_pin_detach_irq(enc_sub->pin_a);
65+
rt_pin_detach_irq(enc_sub->pin_b);
66+
67+
rt_free(enc_sub);
68+
69+
return RT_EOK;
70+
}
71+
72+
ab_phase_encoder_t ab_phase_encoder_create(rt_base_t pin_a, rt_base_t pin_b, rt_uint16_t pulse_revol)
73+
{
74+
// Malloc memory and initialize pulse_count and pin
75+
ab_phase_encoder_t new_encoder = (ab_phase_encoder_t)encoder_create(sizeof(struct ab_phase_encoder));
76+
if(new_encoder == RT_NULL)
77+
{
78+
return RT_NULL;
79+
}
80+
81+
new_encoder->pin_a = pin_a;
82+
new_encoder->pin_b = pin_b;
83+
new_encoder->last_value = 0;
84+
new_encoder->enc.pulse_revol = pulse_revol;
85+
new_encoder->enc.enable = ab_phase_encoder_enable;
86+
new_encoder->enc.disable = ab_phase_encoder_disable;
87+
new_encoder->enc.destroy = ab_phase_encoder_destroy;
88+
89+
return new_encoder;
90+
}

encoder/ab_phase_encoder.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef __AB_PHASE_ENCODER_H__
2+
#define __AB_PHASE_ENCODER_H__
3+
4+
#include "encoder.h"
5+
6+
struct ab_phase_encoder
7+
{
8+
struct encoder enc;
9+
rt_base_t pin_a; /* interrupt pin */
10+
rt_base_t pin_b;
11+
rt_int16_t last_value;
12+
};
13+
14+
typedef struct ab_phase_encoder *ab_phase_encoder_t;
15+
16+
ab_phase_encoder_t ab_phase_encoder_create(rt_base_t pin_a, rt_base_t pin_b, rt_uint16_t pulse_revol);
17+
18+
#endif // __AB_PHASE_ENCODER_H__

encoder/encoder.c

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,98 +5,106 @@
55
#define DBG_LEVEL DBG_LOG
66
#include <rtdbg.h>
77

8-
void encoder_isr(void *args)
8+
encoder_t encoder_create(rt_size_t size)
99
{
10-
rt_uint16_t* pulse_count = (rt_uint16_t*)args;
11-
(*pulse_count)++;
12-
// LOG_D("Count %d", *pulse_count);
13-
}
14-
15-
encoder_t encoder_create(rt_base_t pin, rt_uint16_t pulse_revol)
16-
{
17-
// Malloc memory and initialize pulse_count and pin
18-
encoder_t new_encoder = (encoder_t)rt_malloc(sizeof(struct encoder));
10+
// Malloc memory and initialize
11+
encoder_t new_encoder = (encoder_t)rt_malloc(size);
1912
if(new_encoder == RT_NULL)
2013
{
2114
LOG_E("Failed to malloc memory for new encoder\n");
2215
return RT_NULL;
2316
}
2417

2518
new_encoder->pulse_count = 0;
26-
new_encoder->pin = pin;
27-
new_encoder->pulse_revol = pulse_revol;
2819
new_encoder->last_count = 0;
2920

3021
return new_encoder;
3122
}
3223

33-
void encoder_destroy(encoder_t enc)
24+
rt_err_t encoder_destroy(encoder_t enc)
3425
{
3526
LOG_D("Free Encoder");
27+
RT_ASSERT(enc != RT_NULL);
3628

37-
rt_free(enc);
29+
return enc->destroy(enc);
3830
}
3931

4032
rt_err_t encoder_enable(encoder_t enc)
4133
{
4234
LOG_D("Enabling encoder");
35+
RT_ASSERT(enc != RT_NULL);
4336

44-
// Attach interrupts
45-
rt_pin_mode(enc->pin, PIN_MODE_INPUT_PULLUP);
46-
rt_pin_attach_irq(enc->pin, PIN_IRQ_MODE_FALLING, encoder_isr, &(enc->pulse_count));
47-
enc->last_time = rt_tick_get();
48-
49-
return rt_pin_irq_enable(enc->pin, PIN_IRQ_ENABLE);
37+
return enc->enable(enc);
5038
}
5139

5240
rt_err_t encoder_disable(encoder_t enc)
5341
{
5442
LOG_D("Diabling encoder");
43+
RT_ASSERT(enc != RT_NULL);
5544

56-
return rt_pin_detach_irq(enc->pin);
45+
return enc->disable(enc);
5746
}
5847

5948
rt_int16_t encoder_read(encoder_t enc)
6049
{
50+
RT_ASSERT(enc != RT_NULL);
51+
6152
return enc->pulse_count;
6253
}
6354

6455
rt_err_t encoder_reset(encoder_t enc)
6556
{
66-
enc -> pulse_count = 0;
57+
RT_ASSERT(enc != RT_NULL);
58+
59+
enc->pulse_count = 0;
60+
6761
return RT_EOK;
6862
}
6963

7064
rt_int16_t encoder_measure_cps(encoder_t enc)
7165
{
66+
RT_ASSERT(enc != RT_NULL);
7267
// TODO
7368
// return count per second
7469
if((rt_tick_get() - enc->last_time) < rt_tick_from_millisecond(enc->sample_time))
7570
{
76-
// LOG_D("Encoder waiting ... ");
77-
// LOG_D("Current count per second %d", enc->cps);
71+
LOG_D("Encoder waiting ... ");
7872
return enc->cps;
7973
}
8074

81-
enc->cps = (enc->pulse_count - enc->last_count) * 1000 / enc->sample_time;
75+
rt_int32_t diff_count = enc->pulse_count - enc->last_count;
76+
77+
// if (diff_count >= INT32_MAX)
78+
// {
79+
// diff_count = -(enc->pulse_count + enc->last_count);
80+
// }
81+
// if (diff_count <= INT32_MIN)
82+
// {
83+
// diff_count = enc->pulse_count + enc->last_count;
84+
// }
85+
86+
enc->cps = diff_count * 1000 / enc->sample_time;
8287
enc->last_count = enc->pulse_count;
8388
enc->last_time = rt_tick_get();
84-
// LOG_D("Current count per second %d", enc->cps);
8589

8690
return enc->cps;
8791
}
8892

8993
rt_int16_t encoder_measure_rpm(encoder_t enc)
9094
{
95+
RT_ASSERT(enc != RT_NULL);
96+
9197
// return resolution per minute
92-
// LOG_D("Current count per revolution %d", enc->pulse_revol);
93-
9498
rt_int16_t res_rpm = encoder_measure_cps(enc) * 60 / enc->pulse_revol;
95-
// LOG_D("Current revol per minute %d", res_rpm);
99+
96100
return res_rpm;
97101
}
98102

99-
void encoder_set_sample_time(encoder_t enc, rt_uint16_t sample_time)
103+
rt_err_t encoder_set_sample_time(encoder_t enc, rt_uint16_t sample_time)
100104
{
105+
RT_ASSERT(enc != RT_NULL);
106+
101107
enc->sample_time = sample_time;
108+
109+
return RT_EOK;
102110
}

encoder/encoder.h

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,41 @@
22
#define __ENCODER_H__
33

44
#include <rtthread.h>
5+
#include <rtdevice.h>
56

6-
struct encoder
7+
enum encoder_direction
78
{
8-
rt_base_t pin; /* interrupt pin */
9-
rt_int16_t pulse_count; /* absolute pulse number in total */
10-
rt_uint16_t pulse_revol; /* pulse number per revolution */
11-
rt_uint16_t sample_time; /* sample time in microseconds for speed measurement */
12-
rt_tick_t last_time;
13-
rt_int16_t last_count;
14-
rt_int16_t cps;
9+
ENCODER_DIR_FORWARD,
10+
ENCODER_DIR_BACKWARD,
1511
};
1612

1713
typedef struct encoder *encoder_t;
1814

19-
encoder_t encoder_create(rt_base_t pin, rt_uint16_t pulse_revol);
20-
void encoder_destroy(encoder_t enc);
15+
struct encoder
16+
{
17+
rt_int32_t pulse_count; /* absolute pulse number in total */
18+
rt_uint16_t pulse_revol; /* pulse number per revolution */
19+
rt_uint16_t sample_time; /* sample time in microseconds for speed measurement */
20+
rt_tick_t last_time;
21+
rt_int32_t last_count;
22+
rt_int16_t cps;
23+
enum encoder_direction dir;
24+
rt_err_t (*enable)(encoder_t enc);
25+
rt_err_t (*disable)(encoder_t enc);
26+
rt_err_t (*destroy)(encoder_t enc);
27+
};
2128

22-
rt_err_t encoder_enable(encoder_t enc); /* start measurement */
23-
rt_err_t encoder_disable(encoder_t enc); /* stop measurement */
24-
rt_err_t encoder_reset(encoder_t enc); /* set pulse_count to 0 */
29+
encoder_t encoder_create(rt_size_t size);
30+
rt_err_t encoder_destroy(encoder_t enc);
31+
rt_err_t encoder_enable(encoder_t enc); /* start measurement */
32+
rt_err_t encoder_disable(encoder_t enc); /* stop measurement */
33+
rt_err_t encoder_reset(encoder_t enc); /* set pulse_count to 0 */
2534

26-
void encoder_set_sample_time(encoder_t enc, rt_uint16_t sample_time); /* set sample time */
35+
rt_err_t encoder_set_sample_time(encoder_t enc, rt_uint16_t sample_time); /* set sample time */
2736

2837
/** rpm = pulse_count / sample_time(ms) / pulse_revol * 1000 * 60 **/
29-
rt_int16_t encoder_read(encoder_t enc); /* return pulse_count */
30-
rt_int16_t encoder_measure_cps(encoder_t enc); /* pulse_count per second */
31-
rt_int16_t encoder_measure_rpm(encoder_t enc); /* revolutions per minute */
32-
33-
// Encoder Thread
38+
rt_int16_t encoder_read(encoder_t enc); /* return pulse_count */
39+
rt_int16_t encoder_measure_cps(encoder_t enc); /* pulse_count per second */
40+
rt_int16_t encoder_measure_rpm(encoder_t enc); /* revolutions per minute */
3441

3542
#endif

encoder/encoder_AB.c

Whitespace-only changes.

encoder/encoder_AB.h

Whitespace-only changes.

encoder/encoder_single.c

Whitespace-only changes.

encoder/encoder_single.h

Whitespace-only changes.

encoder/single_phase_encoder.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "single_phase_encoder.h"
2+
3+
#define DBG_SECTION_NAME "single_phase_encoder"
4+
#define DBG_LEVEL DBG_LOG
5+
#include <rtdbg.h>
6+
7+
static void encoder_isr(void *args)
8+
{
9+
rt_int32_t* pulse_count = (rt_int32_t*)args;
10+
(*pulse_count)++;
11+
// LOG_D("Count %d", *pulse_count);
12+
}
13+
14+
static rt_err_t single_phase_encoder_enable(encoder_t enc)
15+
{
16+
RT_ASSERT(enc != RT_NULL);
17+
18+
single_phase_encoder_t enc_sub = (single_phase_encoder_t)enc;
19+
20+
// Attach interrupts
21+
rt_pin_mode(enc_sub->pin, PIN_MODE_INPUT_PULLUP);
22+
rt_pin_attach_irq(enc_sub->pin, PIN_IRQ_MODE_FALLING, encoder_isr, &(enc_sub->enc.pulse_count));
23+
enc_sub->enc.last_time = rt_tick_get();
24+
25+
return rt_pin_irq_enable(enc_sub->pin, PIN_IRQ_ENABLE);
26+
}
27+
28+
static rt_err_t single_phase_encoder_disable(encoder_t enc)
29+
{
30+
RT_ASSERT(enc != RT_NULL);
31+
32+
single_phase_encoder_t enc_sub = (single_phase_encoder_t)enc;
33+
34+
return rt_pin_irq_enable(enc_sub->pin, PIN_IRQ_DISABLE);;
35+
}
36+
37+
static rt_err_t single_phase_encoder_destroy(encoder_t enc)
38+
{
39+
RT_ASSERT(enc != RT_NULL);
40+
41+
single_phase_encoder_disable(enc);
42+
single_phase_encoder_t enc_sub = (single_phase_encoder_t)enc;
43+
rt_pin_detach_irq(enc_sub->pin);
44+
45+
rt_free(enc);
46+
47+
return RT_EOK;
48+
}
49+
50+
single_phase_encoder_t single_phase_encoder_create(rt_base_t pin,rt_uint16_t pulse_revol)
51+
{
52+
// Malloc memory and initialize pulse_count and pin
53+
single_phase_encoder_t new_encoder = (single_phase_encoder_t)encoder_create(sizeof(struct single_phase_encoder));
54+
if(new_encoder == RT_NULL)
55+
{
56+
return RT_NULL;
57+
}
58+
59+
new_encoder->pin = pin;
60+
new_encoder->enc.pulse_revol = pulse_revol;
61+
new_encoder->enc.enable = single_phase_encoder_enable;
62+
new_encoder->enc.disable = single_phase_encoder_disable;
63+
new_encoder->enc.destroy = single_phase_encoder_destroy;
64+
65+
return new_encoder;
66+
}

encoder/single_phase_encoder.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef __SINGLE_PHASE_ENCODER_H__
2+
#define __SINGLE_PHASE_ENCODER_H__
3+
4+
#include "encoder.h"
5+
6+
struct single_phase_encoder
7+
{
8+
struct encoder enc;
9+
rt_base_t pin; /* interrupt pin */
10+
};
11+
12+
typedef struct single_phase_encoder *single_phase_encoder_t;
13+
14+
single_phase_encoder_t single_phase_encoder_create(rt_base_t pin, rt_uint16_t pulse_revol);
15+
16+
#endif // __SINGLE_PHASE_ENCODER_H__

0 commit comments

Comments
 (0)