analogWrite() на любом выводе
- Войдите на сайт для отправки комментариев
Втр, 05/02/2013 - 06:37
Не раз уже поднималась тема о генерации ШИМа на любом из выводов или на всех выводах сразу. Написал простенькую библиотеку, которая позволяет Ардуино программно генерить 8-ми битный ШИМ на любом из выводов. Библиотека использует TIMER2, тестировалась только на Atmega48/88/168/328, то есть Uno, Duemilanove, Nano и т.п.
И так. Качаем архив, распаковываем его как обычно в ...\arduino-1.х\libraries\ , запускаем IDE, в примерах должна появиться вкладка PWM и в ней 3 примера.
Описание функций:
Пример:
01
#include <PWM.h>
02
03
int
brightness = 0;
// how bright the LED is
04
int
fadeAmount = 5;
// how many points to fade the LED by
05
06
void
setup
() {
07
// declare pin 13 to be an output:
08
analog.Mode(13, OUTPUT);
09
}
10
11
void
loop
() {
12
// set the brightness of pin 13:
13
analog.Write(13, brightness);
14
15
// change the brightness for next time through the loop:
16
brightness = brightness + fadeAmount;
17
18
// reverse the direction of the fading at the ends of the fade:
19
if
(brightness == 0 || brightness == 255) {
20
fadeAmount = -fadeAmount ;
21
}
22
// wait for 30 milliseconds to see the dimming effect
23
delay(30);
24
}
Видео
Понятненько. Интересная библиотечка.
Для леонардо и меги редактируем файл pins.h согласно пин-маппингу.
В итоге все пришло к тому, что как таковая библиотека не нужна.
Создайте в своем проекте новую вкладку с именем PWM:
и копируйте туда это содержимое:
001
#ifdef ALL
002
#define PIN_0
003
#define PIN_1
004
#define PIN_2
005
#define PIN_3
006
#define PIN_4
007
#define PIN_5
008
#define PIN_6
009
#define PIN_7
010
#define PIN_8
011
#define PIN_9
012
#define PIN_10
013
#define PIN_11
014
#define PIN_12
015
#define PIN_13
016
#define PIN_14
017
#define PIN_15
018
#define PIN_16
019
#define PIN_17
020
#define PIN_18
021
#define PIN_19
022
#endif
023
024
#define SBI(port, pin) asm volatile ("sbi %0, %1" :: "I" (_SFR_IO_ADDR(port)), "I" (pin))
025
026
#define CHECK(pwms, port, pin) \
027
asm volatile ( \
028
"cpc %0, %1 \n\t"
\
029
"brlo 0f \n\t"
\
030
"cbi %2, %3 \n\t"
\
031
"rjmp 1f \n\t"
\
032
"0: sbi %2, %3 \n\t"
\
033
"1: nop \n\t"
\
034
:
"+r"
(pwm),
"+r"
(pwms) \
035
:
"I"
(_SFR_IO_ADDR(port)),
"I"
(pin)\
036
)\
037
038
void
Init_PWM()
039
{
040
cli();
041
TCCR2A = 0;
042
TCCR2B = 3;
//CLK
043
OCR2A = 1;
044
TIMSK2 = 2;
//разрешаем прерывание по совпадению
045
sei();
046
047
#ifdef PIN_0
048
SBI(DDRD, 0);
049
#endif
050
#ifdef PIN_1
051
SBI(DDRD, 1);
052
#endif
053
#ifdef PIN_2
054
SBI(DDRD, 2);
055
#endif
056
#ifdef PIN_3
057
SBI(DDRD, 3);
058
#endif
059
#ifdef PIN_4
060
SBI(DDRD, 4);
061
#endif
062
#ifdef PIN_5
063
SBI(DDRD, 5);
064
#endif
065
#ifdef PIN_6
066
SBI(DDRD, 6);
067
#endif
068
#ifdef PIN_7
069
SBI(DDRD, 7);
070
#endif
071
#ifdef PIN_8
072
SBI(DDRB, 0);
073
#endif
074
#ifdef PIN_9
075
SBI(DDRB, 1);
076
#endif
077
#ifdef PIN_10
078
SBI(DDRB, 2);
079
#endif
080
#ifdef PIN_11
081
SBI(DDRB, 3);
082
#endif
083
#ifdef PIN_12
084
SBI(DDRB, 4);
085
#endif
086
#ifdef PIN_13
087
SBI(DDRB, 5);
088
#endif
089
#ifdef PIN_14
090
SBI(DDRC, 0);
091
#endif
092
#ifdef PIN_15
093
SBI(DDRC, 1);
094
#endif
095
#ifdef PIN_16
096
SBI(DDRC, 2);
097
#endif
098
#ifdef PIN_17
099
SBI(DDRC, 3);
100
#endif
101
#ifdef PIN_18
102
SBI(DDRC, 4);
103
#endif
104
#ifdef PIN_19
105
SBI(DDRC, 5);
106
#endif
107
}
108
109
volatile uint8_t pwm;
110
volatile uint8_t pwms[20];
111
112
void
analog_Frequence(
byte
prescaler)
113
{
114
TCCR2B = prescaler;
//CLK
115
}
116
117
void
analog_Write(
byte
pin,
byte
value)
118
{
119
pwms[pin] = value;
120
}
121
122
byte
analog_State(
byte
pin)
123
{
124
return
pwms[pin];
125
}
126
127
ISR(TIMER2_COMPA_vect)
128
{
129
asm volatile (
"clr %0"
:
"+r"
(TCNT2));
// TCNT2 = 0;
130
131
#ifdef PIN_0
132
CHECK(pwms[0], PORTD, 0);
133
#endif
134
#ifdef PIN_1
135
CHECK(pwms[1], PORTD, 1);
136
#endif
137
#ifdef PIN_2
138
CHECK(pwms[2], PORTD, 2);
139
#endif
140
#ifdef PIN_3
141
CHECK(pwms[3], PORTD, 3);
142
#endif
143
#ifdef PIN_4
144
CHECK(pwms[4], PORTD, 4);
145
#endif
146
#ifdef PIN_5
147
CHECK(pwms[5], PORTD, 5);
148
#endif
149
#ifdef PIN_6
150
CHECK(pwms[6], PORTD, 6);
151
#endif
152
#ifdef PIN_7
153
CHECK(pwms[7], PORTD, 7);
154
#endif
155
#ifdef PIN_8
156
CHECK(pwms[8], PORTB, 0);
157
#endif
158
#ifdef PIN_9
159
CHECK(pwms[9], PORTB, 1);
160
#endif
161
#ifdef PIN_10
162
CHECK(pwms[10], PORTB, 2);
163
#endif
164
#ifdef PIN_11
165
CHECK(pwms[11], PORTB, 3);
166
#endif
167
#ifdef PIN_12
168
CHECK(pwms[12], PORTB, 4);
169
#endif
170
#ifdef PIN_13
171
CHECK(pwms[13], PORTB, 5);
172
#endif
173
#ifdef PIN_14
174
CHECK(pwms[14], PORTC, 0);
175
#endif
176
#ifdef PIN_15
177
CHECK(pwms[15], PORTC, 1);
178
#endif
179
#ifdef PIN_16
180
CHECK(pwms[16], PORTC, 2);
181
#endif
182
#ifdef PIN_17
183
CHECK(pwms[17], PORTC, 3);
184
#endif
185
#ifdef PIN_18
186
CHECK(pwms[18], PORTC, 4);
187
#endif
188
#ifdef PIN_19
189
CHECK(pwms[19], PORTC, 5);
190
#endif
191
192
asm volatile (
"inc %0"
:
"+r"
(pwm));
//pwm++;
193
}
пример кода:
01
#define PIN_12
02
#define PIN_13
03
04
int
brightness = 0;
// how bright the LED is
05
int
fadeAmount = 5;
// how many points to fade the LED by
06
07
void
setup
()
08
{
09
Init_PWM();
10
analog_Frequence(2);
// предделитель от 1 до 7
11
}
12
13
void
loop
()
14
{
15
analog_Write(12, 255-brightness);
16
analog_Write(13, brightness);
17
18
brightness = brightness + fadeAmount;
19
20
if
(brightness == 0 || brightness == 255) fadeAmount = -fadeAmount ;
21
22
delay(50);
23
}
P.S. #define ALL задействует все 20 выводов дуины.
У меги и так шимов много. Для меги имеет смысл применять только на выходы больше 20.
С другой стороны, либа позволяет высвободить таймер1 для себя :)
На 8 меге гугаетсо
1
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp: In constructor
'PWM::PWM()'
:
2
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp:17: error:
'TCCR2A'
was not declared
in
this
scope
3
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp:18: error:
'TCCR2B'
was not declared
in
this
scope
4
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp:19: error:
'OCR2A'
was not declared
in
this
scope
5
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp:20: error:
'TIMSK2'
was not declared
in
this
scope
6
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp: In member function
'void PWM::Frequence(byte)'
:
7
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp:29: error:
'TCCR2B'
was not declared
in
this
scope
8
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp: At global scope:
9
C:\MC\arduino-1.0.4\libraries\PWM\PWM.cpp:36: warning:
'TIMER2_COMPA_vect'
appears to be a misspelled signal handler
А так хочется ещё пару ножек с ШИМ"мом :(
Потому что на меге8 отсутстует таймер2.
Можно немного глупый вопрос, а первый можно задействовать?
Конечно можно. По аналогии можете сделать, только лучше делать сразу для конкретных выводов ,тогда работать будет быстрее.
Тоесть все что имеет в тексте TCCR2A, TCCR2B, OCR2A, TIMSK2, TCCR2B, TIMER2_COMPA_vect изменить на 1 или как?
Вот бы как в дуинки уно... тоесть как в меги 328 были все ноги что поддерживают ШИМ имели поддержку у меги 8-й.
Почти, только таймер1 16битный, а следовательно некоторые регистры состоят из младшего и старшего реистров.
Например на OCR1A компилятор ругнтся так как он 16-битный и состоит из OCR1AH и OCR1AL.
Понятно... что ничего непонятно...
Просто сменить 2-ки на 1-ки неполучилось.
Понятно... что ничего непонятно...
Просто сменить 2-ки на 1-ки неполучилось.
atmega88 - не?
Я пользуюсь ATmega8A-PU.
Я пользуюсь ATmega8A-PU.
Можно ведь постепенно переползать на более современные камни - по сравнению с мега8-й разницы не заметите, но присутсвуют плюшки аппаратной и программной совместимости с фирменными дуино.
Можно, но пока будут современные камни плыть из Китая перебиваться буду тем что есть.
Не плохо ! На меге мне удалось максимум задействовать 14 пинов! А реально их все задействовать под "ШИМ" имея в виду 54 пина? Тут в ...\PWM\PINS изменения сделал, надеясь хотя б 32 зажечь
01
#define HIGH_0 PORTD|=1<<0
02
#define HIGH_1 PORTD|=1<<1
03
#define HIGH_2 PORTD|=1<<2
04
#define HIGH_3 PORTD|=1<<3
05
#define HIGH_4 PORTD|=1<<4
06
#define HIGH_5 PORTD|=1<<5
07
#define HIGH_6 PORTD|=1<<6
08
#define HIGH_7 PORTD|=1<<7
09
#define HIGH_8 PORTB|=1<<0
10
#define HIGH_9 PORTB|=1<<1
11
#define HIGH_10 PORTB|=1<<2
12
#define HIGH_11 PORTB|=1<<3
13
#define HIGH_12 PORTB|=1<<4
14
#define HIGH_13 PORTB|=1<<5
15
#define HIGH_14 PORTB|=1<<6
16
#define HIGH_15 PORTB|=1<<7
17
#define HIGH_16 PORTC|=1<<0
18
#define HIGH_17 PORTC|=1<<1
19
#define HIGH_18 PORTC|=1<<2
20
#define HIGH_19 PORTC|=1<<3
21
#define HIGH_20 PORTC|=1<<4
22
#define HIGH_21 PORTC|=1<<5
23
#define HIGH_22 PORTC|=1<<6
24
#define HIGH_23 PORTC|=1<<7
25
#define HIGH_24 PORTH|=1<<0
26
#define HIGH_25 PORTH|=1<<1
27
#define HIGH_26 PORTH|=1<<2
28
#define HIGH_27 PORTH|=1<<3
29
#define HIGH_28 PORTH|=1<<4
30
#define HIGH_29 PORTH|=1<<5
31
#define HIGH_30 PORTH|=1<<6
32
#define HIGH_31 PORTH|=1<<7
33
34
35
36
#define LOW_0 PORTD&=~(1<<0)
37
#define LOW_1 PORTD&=~(1<<1)
38
#define LOW_2 PORTD&=~(1<<2)
39
#define LOW_3 PORTD&=~(1<<3)
40
#define LOW_4 PORTD&=~(1<<4)
41
#define LOW_5 PORTD&=~(1<<5)
42
#define LOW_6 PORTD&=~(1<<6)
43
#define LOW_7 PORTD&=~(1<<7)
44
#define LOW_8 PORTB&=~(1<<0)
45
#define LOW_9 PORTB&=~(1<<1)
46
#define LOW_10 PORTB&=~(1<<2)
47
#define LOW_11 PORTB&=~(1<<3)
48
#define LOW_12 PORTB&=~(1<<4)
49
#define LOW_13 PORTB&=~(1<<5)
50
#define LOW_14 PORTB&=~(1<<6)
51
#define LOW_15 PORTB&=~(1<<7)
52
#define LOW_16 PORTC&=~(1<<0)
53
#define LOW_17 PORTC&=~(1<<1)
54
#define LOW_18 PORTC&=~(1<<2)
55
#define LOW_19 PORTC&=~(1<<3)
56
#define LOW_20 PORTC&=~(1<<4)
57
#define LOW_21 PORTC&=~(1<<5)
58
#define LOW_22 PORTC&=~(1<<6)
59
#define LOW_23 PORTC&=~(1<<7)
60
#define LOW_24 PORTH&=~(1<<0)
61
#define LOW_25 PORTH&=~(1<<1)
62
#define LOW_26 PORTH&=~(1<<2)
63
#define LOW_27 PORTH&=~(1<<3)
64
#define LOW_28 PORTH&=~(1<<4)
65
#define LOW_29 PORTH&=~(1<<5)
66
#define LOW_30 PORTH&=~(1<<6)
67
#define LOW_31 PORTH&=~(1<<7)
для экперимента, без успешно! (( Или я не там прописал !??
Еще нужно файл PWM.cpp подправить:
01
#include "PWM.h"
02
03
PWM::PWM()
04
{
05
cli();
06
TCCR2A = 0;
//при совпадении уровень OC1A меняется на противоположный
07
TCCR2B = 5;
//CLK
08
OCR2A = 1;
09
TIMSK2 = 2;
//разрешаем прерывание по совпадению
10
sei();
11
12
13
}
14
15
16
void
PWM::Frequence(
byte
prescaler)
17
{
18
TCCR2B = prescaler;
//CLK
19
}
20
21
22
volatile
byte
pwms[32];
23
24
ISR(TIMER2_COMPA_vect)
25
{
26
TCNT2 = 0;
27
static
byte
pwm;
28
pwms[0] > pwm ? HIGH_0 : LOW_0;
29
pwms[1] > pwm ? HIGH_1 : LOW_1;
30
pwms[2] > pwm ? HIGH_2 : LOW_2;
31
pwms[3] > pwm ? HIGH_3 : LOW_3;
32
pwms[4] > pwm ? HIGH_4 : LOW_4;
33
pwms[5] > pwm ? HIGH_5 : LOW_5;
34
pwms[6] > pwm ? HIGH_6 : LOW_6;
35
pwms[7] > pwm ? HIGH_7 : LOW_7;
36
pwms[8] > pwm ? HIGH_8 : LOW_8;
37
pwms[9] > pwm ? HIGH_9 : LOW_9;
38
pwms[10] > pwm ? HIGH_10 : LOW_10;
39
pwms[11] > pwm ? HIGH_11 : LOW_11;
40
pwms[12] > pwm ? HIGH_12 : LOW_12;
41
pwms[13] > pwm ? HIGH_13 : LOW_13;
42
pwms[14] > pwm ? HIGH_14 : LOW_14;
43
pwms[15] > pwm ? HIGH_15 : LOW_15;
44
pwms[16] > pwm ? HIGH_16 : LOW_16;
45
pwms[17] > pwm ? HIGH_17 : LOW_17;
46
pwms[18] > pwm ? HIGH_18 : LOW_18;
47
pwms[19] > pwm ? HIGH_19 : LOW_19;
48
pwms[20] > pwm ? HIGH_20 : LOW_20;
49
pwms[21] > pwm ? HIGH_21 : LOW_21;
50
pwms[22] > pwm ? HIGH_22 : LOW_22;
51
pwms[23] > pwm ? HIGH_23 : LOW_23;
52
pwms[24] > pwm ? HIGH_24 : LOW_24;
53
pwms[25] > pwm ? HIGH_25 : LOW_25;
54
pwms[26] > pwm ? HIGH_26 : LOW_26;
55
pwms[27] > pwm ? HIGH_27 : LOW_27;
56
pwms[28] > pwm ? HIGH_28 : LOW_28;
57
pwms[29] > pwm ? HIGH_29 : LOW_29;
58
pwms[30] > pwm ? HIGH_30 : LOW_30;
59
pwms[31] > pwm ? HIGH_31 : LOW_31;
60
pwm++;
61
if
(pwm == 255) pwm = 0;
62
}
63
64
65
void
PWM::Mode(
byte
pin,
bool
en)
66
{
67
for
(
byte
i = 0; i < 32; i++)
68
{
69
pinMode(i, en);
70
}
71
}
72
73
74
void
PWM::Write(
byte
pin,
byte
value)
75
{
76
pwms[pin] = value;
77
}
78
79
80
byte
PWM::State(
byte
pin)
81
{
82
return
pwms[pin];
83
}
84
85
PWM analog = PWM();
Если процессорного времени хватит, то можно и все 54 задействовать, если же нет то нужно разрядность ШИМа понижать.
Большое спасибо за быструю реакцию! Попробывал предварительно : сменил в PWM.cpp начинку на предложенную, дополнив сразу до 54 пинов! и в ...\PWM\PINS не забыл . И все тоже самое работают в ШИМе только PB4-PB7(10-13),PD0-PD3(18-21)! ( И ещё, если делаю в скетче доп.ю инициализацию в
void setup()
{pinMode(0, OUTPUT);pinMode(1, OUTPUT);........pinMode(54, OUTPUT);
analog.Mode(0, OUTPUT);analog.Mode(1, OUTPUT);..........analog.Mode(54, OUTPUT);}
то начинает работать и PC0-PC4,PD7(33-38)! ( Вроде правильно вычислил..) А остальные молчат !(( А хотелось бы научиться,надеюсь это возможно, на всех портах(пинах) МЕГИ... Может что ещё мы не сделали??
Выводы на выход в этом случае можно настраивать целыми портами:
1
DDRA = 0xFF;
2
DDRB = 0xFF;
3
DDRC = 0xFF;
4
DDRF = 0xFF;
5
DDRK = 0xFF;
попробуйте снизить частоту:
и уменьшить разрядность:
60
pwm++;
61
if
(pwm == 100) pwm = 0;
62
}
СПАСИБО Максим!
И так. Качаем архив, распаковываем его как обычно в ...\arduino-1.х\libraries\ , запускаем IDE, в примерах должна появиться вкладка PWM и в ней 3 примера.
Перезалейте пожалуйста архив.
Перезалейте пожалуйста архив, по Вашей сылке битый.
http://webfile.ru/7d24c4665bbe34036aad195a00b72bdc
Тоже хочу использовать составной 2-х монитор, но есть информация о 4-х или 6-х рамочном + контроллерном объединителе.
Какая у вас модель?
Спасибо.
а вот частоту следования шим, можно изменить, повысить до 3кгц?
Нет.
А какая частота программного ШИМа? На глаз мерцание не заметно, понятно что больше 24 герц.
Да фиг его знает какая, измерьте. А насчет не видно... я например и 3 кГц вижу - когда взгляд отводишь в сторону видны шлейфы.
Может чуть позже выложу данную либу с возможностью задавать выводы до компиляции кода (через директивы препроцессора), а управление выводами через asm-вставки будут организованы, что сэкономит "пару" тактов на обработку кажного вывода. В результате можно будет при небольшом количестве выводов значительно увеличить частоту.
Как обещал - новая версия либы. Старую удалить. Как таковая библиотека отсутствует, все находится в файле PWM.ino, который вложен в примеры.
Пример:
01
#define PIN_12
02
#define PIN_13
03
04
int
brightness = 0;
// how bright the LED is
05
int
fadeAmount = 5;
// how many points to fade the LED by
06
07
void
setup
()
08
{
09
Init_PWM();
10
analog_Frequence(2);
// предделитель от 1 до 7
11
}
12
13
void
loop
()
14
{
15
analog_Write(12, 255-brightness);
16
analog_Write(13, brightness);
17
18
brightness = brightness + fadeAmount;
19
20
if
(brightness == 0 || brightness == 255) fadeAmount = -fadeAmount ;
21
22
delay(50);
23
}
PWM.ino:
001
#ifdef ALL
002
#define PIN_0
003
#define PIN_1
004
#define PIN_2
005
#define PIN_3
006
#define PIN_4
007
#define PIN_5
008
#define PIN_6
009
#define PIN_7
010
#define PIN_8
011
#define PIN_9
012
#define PIN_10
013
#define PIN_11
014
#define PIN_12
015
#define PIN_13
016
#define PIN_14
017
#define PIN_15
018
#define PIN_16
019
#define PIN_17
020
#define PIN_18
021
#define PIN_19
022
#endif
023
024
#define SBI(port, pin) asm volatile ("sbi %0, %1" :: "I" (_SFR_IO_ADDR(port)), "I" (pin))
025
026
#define CHECK(pwms, port, pin) \
027
asm volatile ( \
028
"cpc %0, %1 \n\t"
\
029
"brlo 0f \n\t"
\
030
"cbi %2, %3 \n\t"
\
031
"rjmp 1f \n\t"
\
032
"0: sbi %2, %3 \n\t"
\
033
"1: nop \n\t"
\
034
:
"+r"
(pwm),
"+r"
(pwms) \
035
:
"I"
(_SFR_IO_ADDR(port)),
"I"
(pin)\
036
)\
037
038
void
Init_PWM()
039
{
040
cli();
041
TCCR2A = 0;
042
TCCR2B = 3;
//CLK
043
OCR2A = 1;
044
TIMSK2 = 2;
//разрешаем прерывание по совпадению
045
sei();
046
047
#ifdef PIN_0
048
SBI(DDRD, 0);
049
#endif
050
#ifdef PIN_1
051
SBI(DDRD, 1);
052
#endif
053
#ifdef PIN_2
054
SBI(DDRD, 2);
055
#endif
056
#ifdef PIN_3
057
SBI(DDRD, 3);
058
#endif
059
#ifdef PIN_4
060
SBI(DDRD, 4);
061
#endif
062
#ifdef PIN_5
063
SBI(DDRD, 5);
064
#endif
065
#ifdef PIN_6
066
SBI(DDRD, 6);
067
#endif
068
#ifdef PIN_7
069
SBI(DDRD, 7);
070
#endif
071
#ifdef PIN_8
072
SBI(DDRB, 0);
073
#endif
074
#ifdef PIN_9
075
SBI(DDRB, 1);
076
#endif
077
#ifdef PIN_10
078
SBI(DDRB, 2);
079
#endif
080
#ifdef PIN_11
081
SBI(DDRB, 3);
082
#endif
083
#ifdef PIN_12
084
SBI(DDRB, 4);
085
#endif
086
#ifdef PIN_13
087
SBI(DDRB, 5);
088
#endif
089
#ifdef PIN_14
090
SBI(DDRC, 0);
091
#endif
092
#ifdef PIN_15
093
SBI(DDRC, 1);
094
#endif
095
#ifdef PIN_16
096
SBI(DDRC, 2);
097
#endif
098
#ifdef PIN_17
099
SBI(DDRC, 3);
100
#endif
101
#ifdef PIN_18
102
SBI(DDRC, 4);
103
#endif
104
#ifdef PIN_19
105
SBI(DDRC, 5);
106
#endif
107
}
108
109
volatile uint8_t pwm;
110
volatile uint8_t pwms[20];
111
112
void
analog_Frequence(
byte
prescaler)
113
{
114
TCCR2B = prescaler;
//CLK
115
}
116
117
void
analog_Write(
byte
pin,
byte
value)
118
{
119
pwms[pin] = value;
120
}
121
122
byte
analog_State(
byte
pin)
123
{
124
return
pwms[pin];
125
}
126
127
ISR(TIMER2_COMPA_vect)
128
{
129
asm volatile (
"clr %0"
:
"+r"
(TCNT2));
// TCNT2 = 0;
130
131
#ifdef PIN_0
132
CHECK(pwms[0], PORTD, 0);
133
#endif
134
#ifdef PIN_1
135
CHECK(pwms[1], PORTD, 1);
136
#endif
137
#ifdef PIN_2
138
CHECK(pwms[2], PORTD, 2);
139
#endif
140
#ifdef PIN_3
141
CHECK(pwms[3], PORTD, 3);
142
#endif
143
#ifdef PIN_4
144
CHECK(pwms[4], PORTD, 4);
145
#endif
146
#ifdef PIN_5
147
CHECK(pwms[5], PORTD, 5);
148
#endif
149
#ifdef PIN_6
150
CHECK(pwms[6], PORTD, 6);
151
#endif
152
#ifdef PIN_7
153
CHECK(pwms[7], PORTD, 7);
154
#endif
155
#ifdef PIN_8
156
CHECK(pwms[8], PORTB, 0);
157
#endif
158
#ifdef PIN_9
159
CHECK(pwms[9], PORTB, 1);
160
#endif
161
#ifdef PIN_10
162
CHECK(pwms[10], PORTB, 2);
163
#endif
164
#ifdef PIN_11
165
CHECK(pwms[11], PORTB, 3);
166
#endif
167
#ifdef PIN_12
168
CHECK(pwms[12], PORTB, 4);
169
#endif
170
#ifdef PIN_13
171
CHECK(pwms[13], PORTB, 5);
172
#endif
173
#ifdef PIN_14
174
CHECK(pwms[14], PORTC, 0);
175
#endif
176
#ifdef PIN_15
177
CHECK(pwms[15], PORTC, 1);
178
#endif
179
#ifdef PIN_16
180
CHECK(pwms[16], PORTC, 2);
181
#endif
182
#ifdef PIN_17
183
CHECK(pwms[17], PORTC, 3);
184
#endif
185
#ifdef PIN_18
186
CHECK(pwms[18], PORTC, 4);
187
#endif
188
#ifdef PIN_19
189
CHECK(pwms[19], PORTC, 5);
190
#endif
191
192
asm volatile (
"inc %0"
:
"+r"
(pwm));
//pwm++;
193
}
P.S. #define ALL задействует все 20 выводов дуины.
Спасибо :)
то есть выше 490гц нельзя? синусоиду с частотой 400гц на ноги вывести невозможно?
Почему 490? Как увеличить частоту аппаратного ШИМа читайте тут. Здесвь же программный ШИМ и частота зависит от предделителя и количества задействованых выводов.
4 вывода. один с опорнойй синусоидой а 3 - фазные смещенные относ друг друга на 120. как это грамотно описать?
У меня данная библиотека конфликтует IRRemote на UNO (обе используют TIMER2)
Можно ктото задействовал TIMER1 ?
Или проще IRremote перенастроить ?
Можно сделать как хотите. Как изменить эту любу обсуждалось, а в IRremote есть возможность поменять таймер.
Можно сделать как хотите. Как изменить эту любу обсуждалось, а в IRremote есть возможность поменять таймер.
Спасибо. Таймер поменял в IRremote. Все заработало с пол-пинка
Почему 490? Как увеличить частоту аппаратного ШИМа читайте тут. Здесвь же программный ШИМ и частота зависит от предделителя и количества задействованых выводов.
я о том, можно ли в analogwrite записывать чаще чем 490гц?
суть моей проблемы в том что в analogwrite пишутся значения из массива (256 значений описывающих один период синусоиды). генерируется несущая у которой должна быть частота 400гц на выходе. с частотой шима в 490 я никак не смогу записать 400*256=102400значений в секунду. какие есть варианты?
Не получилось скачать архив. Было интересно посмотреть что там.
Использую эту библиотеку на Arduino Nano. Подключены 1.8 inch TFT color display (HY-1.8 SPI), часы DS1302, датчик температуры и влажности DHT11, энкодер, кнопка и блютуз. На дисплей вывод время/температура, уровень яркости RGB светодиодов. Светодиоды подключены к аналоговым выходам ( analog.Mode(17, OUTPUT); // R и дальше...)
Все это работает, но при опросе датчика температуры (раз в минуту) светодиоды мигают.
1
float
h = dht.readHumidity();
2
float
t = dht.readTemperature();
Я проверял, именно в этом месте светодиоды тухнут. Где-то было написано, что опрос происходит медленно, 250мс. Без подключения библиотеки PWM.h такого не происходит. А мне нехватает ШИМ выходов. Пробовал разные библиотеки DHT11, заработала только одна.
Подскажите, пожалуйста, как с этим бороться? Менять датчик на DHT22?
Я проверял, именно в этом месте светодиоды тухнут. Где-то было написано, что опрос происходит медленно, 250мс. Без подключения библиотеки PWM.h такого не происходит. А мне нехватает ШИМ выходов. Пробовал разные библиотеки DHT11, заработала только одна.
Подскажите, пожалуйста, как с этим бороться? Менять датчик на DHT22?
DHT22 быстрее работать не будет, только точнее. Протокол у него тот же. Можно датчик пореже опрашивать. Но программный PWM все равно будет в это время тормозить. Лучше всего поменять датчик на i2C или аналоговый типа LM335. Тогда опрос будет быстрее.
При стоимости Arduino Pro Micro 3$ может дешевле отдельный контроллер на PWM поставить?
DHT22 быстрее работать не будет, только точнее. Протокол у него тот же. Можно датчик пореже опрашивать. Но программный PWM все равно будет в это время тормозить. Лучше всего поменять датчик на i2C или аналоговый типа LM335. Тогда опрос будет быстрее.
При стоимости Arduino Pro Micro 3$ может дешевле отдельный контроллер на PWM поставить?
Да, скорее всего, буду пробовать отдельный контроллер...
Использую эту библиотеку на Arduino Nano. Подключены 1.8 inch TFT color display (HY-1.8 SPI), часы DS1302, датчик температуры и влажности DHT11, энкодер, кнопка и блютуз. На дисплей вывод время/температура, уровень яркости RGB светодиодов. Светодиоды подключены к аналоговым выходам ( analog.Mode(17, OUTPUT); // R и дальше...)
Все это работает, но при опросе датчика температуры (раз в минуту) светодиоды мигают.
1
float
h = dht.readHumidity();
2
float
t = dht.readTemperature();
Я проверял, именно в этом месте светодиоды тухнут. Где-то было написано, что опрос происходит медленно, 250мс. Без подключения библиотеки PWM.h такого не происходит. А мне нехватает ШИМ выходов. Пробовал разные библиотеки DHT11, заработала только одна.
Подскажите, пожалуйста, как с этим бороться? Менять датчик на DHT22?
Спасибо, maksim! Я понял источник проблемы. Главное, что вся связка у меня работает. Теперь до ума доводить буду.
Поделитесь библиотекой плиииз с первого поста. а то файла больше нет.
Берите эту #30, той уже нет.
Берите эту #30, той уже нет.
Кстати на Leonardo не компилируется.
1
PWM.ino: In function
'void Init_PWM()'
:
2
PWM:43: error:
'TCCR2A'
was not declared
in
this
scope
3
PWM:44: error:
'TCCR2B'
was not declared
in
this
scope
4
PWM:45: error:
'OCR2A'
was not declared
in
this
scope
5
PWM.ino: In function
'void analog_Frequence(byte)'
:
6
PWM:116: error:
'TCCR2B'
was not declared
in
this
scope
7
PWM.ino: In function
'void TIMER2_COMPA_vect()'
:
8
PWM:131: error:
'TCNT2'
was not declared
in
this
scope
Потому что у ATmega32U4 отсутствует второй таймер, а единственный 8-ми битный таймер это TIMER0. В теории если замените двойки на нули должно завестись.
Есть готовый пульт на NANO. Свободны только пины 0 и 1. Можно ли на них генерить шим для управления драйвером шагового двигателя? С помощью библиотеки maksima вроде можно, но не будут ли какие то подводные камни.
Вот так код компилится под мегу 8-ю:
#ifdef ALL
#define PIN_0
#define PIN_1
#define PIN_2
#define PIN_3
#define PIN_4
#define PIN_5
#define PIN_6
#define PIN_7
#define PIN_8
#define PIN_9
#define PIN_10
#define PIN_11
#define PIN_12
#define PIN_13
#define PIN_14
#define PIN_15
#define PIN_16
#define PIN_17
#define PIN_18
#define PIN_19
#endif
#define SBI(port, pin) asm volatile ("sbi %0, %1 \n\t" :: "I" (_SFR_IO_ADDR(port)), "I" (pin))
#define CHECK(pwms, port, pin) \
asm volatile ( \
"cpc %0, %1 \n\t"
\
"brlo 0f \n\t"
\
"cbi %2, %3 \n\t"
\
"rjmp 1f \n\t"
\
"0: sbi %2, %3 \n\t"
\
"1: nop \n\t"
\
:
"+r"
(pwm),
"+r"
(pwms) \
:
"I"
(_SFR_IO_ADDR(port)),
"I"
(pin)\
)\
void
Init_PWM()
{
cli();
TCCR1A = 0;
TCCR1B = 3;
//CLK
OCR1A = 1;
TIMSK = 2;
//разрешаем прерывание по совпадению
sei();
#ifdef PIN_0
SBI(DDRD, 0);
#endif
#ifdef PIN_1
SBI(DDRD, 1);
#endif
#ifdef PIN_2
SBI(DDRD, 2);
#endif
#ifdef PIN_3
SBI(DDRD, 3);
#endif
#ifdef PIN_4
SBI(DDRD, 4);
#endif
#ifdef PIN_5
SBI(DDRD, 5);
#endif
#ifdef PIN_6
SBI(DDRD, 6);
#endif
#ifdef PIN_7
SBI(DDRD, 7);
#endif
#ifdef PIN_8
SBI(DDRB, 0);
#endif
#ifdef PIN_9
SBI(DDRB, 1);
#endif
#ifdef PIN_10
SBI(DDRB, 2);
#endif
#ifdef PIN_11
SBI(DDRB, 3);
#endif
#ifdef PIN_12
SBI(DDRB, 4);
#endif
#ifdef PIN_13
SBI(DDRB, 5);
#endif
#ifdef PIN_14
SBI(DDRC, 0);
#endif
#ifdef PIN_15
SBI(DDRC, 1);
#endif
#ifdef PIN_16
SBI(DDRC, 2);
#endif
#ifdef PIN_17
SBI(DDRC, 3);
#endif
#ifdef PIN_18
SBI(DDRC, 4);
#endif
#ifdef PIN_19
SBI(DDRC, 5);
#endif
}
volatile uint8_t pwm;
volatile uint8_t pwms[20];
void
analog_Frequence(
byte
prescaler)
{
TCCR1B = prescaler;
//CLK
}
void
analog_Write(
byte
pin,
byte
value)
{
pwms[pin] = value;
}
byte
analog_State(
byte
pin)
{
return
pwms[pin];
}
ISR(TIMER1_COMPA_vect)
{
asm volatile (
"clr %0"
:
"+r"
(TCNT2));
// TCNT2 = 0;
#ifdef PIN_0
CHECK(pwms[0], PORTD, 0);
#endif
#ifdef PIN_1
CHECK(pwms[1], PORTD, 1);
#endif
#ifdef PIN_2
CHECK(pwms[2], PORTD, 2);
#endif
#ifdef PIN_3
CHECK(pwms[3], PORTD, 3);
#endif
#ifdef PIN_4
CHECK(pwms[4], PORTD, 4);
#endif
#ifdef PIN_5
CHECK(pwms[5], PORTD, 5);
#endif
#ifdef PIN_6
CHECK(pwms[6], PORTD, 6);
#endif
#ifdef PIN_7
CHECK(pwms[7], PORTD, 7);
#endif
#ifdef PIN_8
CHECK(pwms[8], PORTB, 0);
#endif
#ifdef PIN_9
CHECK(pwms[9], PORTB, 1);
#endif
#ifdef PIN_10
CHECK(pwms[10], PORTB, 2);
#endif
#ifdef PIN_11
CHECK(pwms[11], PORTB, 3);
#endif
#ifdef PIN_12
CHECK(pwms[12], PORTB, 4);
#endif
#ifdef PIN_13
CHECK(pwms[13], PORTB, 5);
#endif
#ifdef PIN_14
CHECK(pwms[14], PORTC, 0);
#endif
#ifdef PIN_15
CHECK(pwms[15], PORTC, 1);
#endif
#ifdef PIN_16
CHECK(pwms[16], PORTC, 2);
#endif
#ifdef PIN_17
CHECK(pwms[17], PORTC, 3);
#endif
#ifdef PIN_18
CHECK(pwms[18], PORTC, 4);
#endif
#ifdef PIN_19
CHECK(pwms[19], PORTC, 5);
#endif
asm volatile (
"inc %0 \n\t"
:
"+r"
(pwm));
//pwm++;
}
Но ничего не происходит :(