Купил я себе у китайцев платку с контроллером STM32F411 с завода она идет с прошитым загрузчиком под STMDUINO. При включении обнаружилось, что светодиод на этой плате плавно загорается а затем гаснет. Делает это загрузчик или прошитый для примера скетч, я тогда разбираться не стал, но эффект мне понравился.
Сейчас праздники, есть немного свободного времени. Вспомнил я про этот эффект и захотелось мне его повторить, но уже на обычной ардуинке. В качестве подопытного мыша, у меня, выступает китайский клон "SparkFun Pro Micro". Если у Вас другая Aduino, подправьте в первой строке привязку к выводу управляющему светодиодом.
01 | #define LED LED_BUILTIN_RX |
02 | #define INTERVAL1 (23u) |
03 | #define INTERVAL2 (24u) |
06 | pinMode (LED, OUTPUT); |
10 | static uint8_t clk1 = 0, clk2 = 0; |
11 | static uint8_t led_state = 0; |
12 | uint8_t now = millis(); |
14 | if (INTERVAL1 < (uint8_t)(now - clk1)) |
20 | if (INTERVAL2 < (uint8_t)(now - clk2)) |
26 | digitalWrite(LED, ((0 == led_state) ? LOW : HIGH)); |
Всех с праздником.
Стандартный из Examples Fade не такой ? По описанию похоже.
Всё не так.
Например millis() совсем не uint8_t, а совсем даже unsigned long. Можно очень даже нарваться.
Почитайте лучше "блинк без делей".
Всё ок. Просто код нарывается на переполнение байта, а не дворда, более того, это не баг, это фича.
ну не знаю, если поменять:
1
led_state ^= 1;
2
3
на
4
5
led_state = !led_state;
вроде более читабельный код, да и по памяти:
01
Скетч использует 824 байт (2%) памяти устройства. Всего доступно 32256 байт.
02
Глобальные переменные используют 12 байт (0%) динамической памяти, оставляя 2036 байт для локальных переменных. Максимум: 2048 байт.
03
04
05
Скетч использует 826 байт (2%) памяти устройства. Всего доступно 32256 байт.
06
Глобальные переменные используют 12 байт (0%) динамической памяти, оставляя 2036 байт для локальных переменных. Максимум: 2048 байт.
07
08
09
А если задействовать сериал, то:
10
11
Скетч использует 2022 байт (6%) памяти устройства. Всего доступно 32256 байт.
12
Глобальные переменные используют 191 байт (9%) динамической памяти, оставляя 1857 байт для локальных переменных. Максимум: 2048 байт.
13
14
Скетч использует 1918 байт (5%) памяти устройства. Всего доступно 32256 байт.
15
Глобальные переменные используют 191 байт (9%) динамической памяти, оставляя 1857 байт для локальных переменных. Максимум: 2048 байт.
Не всё так однозначно, где найдёшь, где потеряешь )))
Всё ок. Просто код нарывается на переполнение байта, а не дворда, более того, это не баг, это фича.
Фича - это косяк. Идею понял, но не одобряю.
Мы расстроены, продолжайте держать нас в курсе :)
На самом деле, нормально. И delay использовать нормально. И даже goto (хоть оно, конечно, почти никогда и не нужно). Реальный мир - он того, не такой, как проповедуют великие теоретики, он полон компромиссов, и неудобностей, и прочего, и хоть я их (теоретиков) и уважаю, но свою голову-то на плечах тоже надо иметь.
А я вообще не понимаю этих перестраховщиков.
Простейший скетч и столько поноса.(
01
#define LED LED_BUILTIN_RX
02
#define INTERVAL1 (23u) //на кой здесь u и скобки?
03
#define INTERVAL2 (24u)
04
#define toggle(x) digitalWrite(x, !digitalRead(x))
05
06
void
setup
() {
07
pinMode (LED, OUTPUT);
08
}
09
10
void
loop
() {
11
static
uint8_t clk1 = 0, clk2 = 0;
//на кой здесь 0-ли?
12
static
uint8_t led_state = 0;
//на кой вообще этот state?
13
uint8_t now = millis();
14
15
if
(INTERVAL1 < (uint8_t)(now - clk1))
//отчего бы не написать по нормальному:
16
if
(now - clk1 > INTERVAL1) {
17
{
//стиль идиотский!
18
clk1 += INTERVAL1;
19
led_state ^= 1;
//toggle(LED);
20
}
21
22
if
(INTERVAL2 < (uint8_t)(now - clk2))
//аналогично
23
{
24
clk2 += INTERVAL2;
25
led_state ^= 1;
26
}
27
28
digitalWrite(LED, ((0 == led_state) ? LOW : HIGH));
//это лишнее и это вообще порнография
29
}
Green, прежде чем ругать чужой, работающий код, да еще с таким наездом, подумали бы хорошенько. Если чего не понятно могли бы спросить и вам бы ответили.
А так, вы только свою безграмотность продемонстрировали.
Green, прежде чем ругать чужой, работающий код, да еще с таким наездом, подумали бы хорошенько. Если чего не понятно могли бы спросить и вам бы ответили.
А так, вы только свою безграмотность продемонстрировали.
nibelung - а что так резко-то? Критики не любите?
"Работающий код" не принято ругать в одном случае - когда он делает что-то важное, что до него никому не удавалось. Вы выложили элементарнейшую мигалку на эффекте интерференции - а ведете себя так, будто как минимум теорему Ферма решили...
Что касакется "безграмотности" - я бы поспорил. Попытайтесь обосновать, зачем вы написали 23u
Попытайтесь обосновать, зачем вы написали 23u
Чтобы объяснить компилятору, что это unsigned константа. По умолчанию все константы имеют тип int (знаковый).
nibelung - а что так резко-то? Критики не любите?
А где там критика? Только самоутверждение за счет новичка. Вот этого не люблю.
Нибелунг! Ща я встану и напишу пост в защиту тебя. Все у тебя правильно. Может слегка избыточно, но правильно и красиво.
Не будь нежным таким, как кожа на залупе, только больше троллить станут.
Некоторые перегибают в чморении новичков. Прости им. ;))
Спасибо на добром слове.
Им простил :))
Чтобы объяснить компилятору, что это unsigned константа. По умолчанию все константы имеют тип int (знаковый).
где ты увидал в этом выражении константу?
Ну вот, троллинг продолжается :)))
где ты увидал в этом выражении константу?
А где ты увидал в этом выражении переменную?
Не будь нежным таким, как кожа на ....
Сразу представилось общение тертого жизней члена форума с молодым и нежным.
"избыточно" и "красиво" вряд ли могут быть синонимами, когда мы говорим о программировании.
Добавление скобок и "u" к величине, применяемой не в составе выражения. а отдельно - скорее свидетесльствует о том, что автор не понимает, что пишет.
Изначально еще хотел написать о избыточности явного приведения разности двух байт к типу uint8_t - но подумал, что сам, наверно, написал бы так же - просто на автомате, чтобы не задумыватся о том, какой тип тут примет компилятор. Но вряд ли такой кастинг "на всякий случай" говорит в пользу "грамотности". скорее просто лень :)
Изначально еще хотел написать о избыточности явного приведения разности двух байт к типу uint8_t - но подумал, что сам, наверно, написал бы так же - просто на автомате, чтобы не задумыватся о том, какой тип тут примет компилятор.
Вот это, кстати, интересное замечание. Написал так, именно на автомате. Потом убрал приведение типа, ибо выглядит немного громоздко. Убедился, что компилятор, ожидаемо, ошибся. И вернул приведение типа на место.
Короче. Влад.
когда встанешь - с радостью выслушаю твою лекцию, зачем тут в выражении
1
#define XX (23u)
скобки и "u" . Только не вообще, а конкретно в этом коде, из первого сообщения.
PS нибелунг - вопрос конкретному человеку, не вам
Так себе код. Если добавить другую нагрузку, то будет работать плохо. Даже как учебный не годится - слишком специфичный и мудреный.
Короче. Влад.
когда встанешь - с радостью выслушаю твою лекцию, зачем тут в выражении
1
#define XX (23u)
скобки и "u" . Только не вообще, а конкретно в этом коде, из первого сообщения.
PS нибелунг - вопрос конкретному человеку, не вам
По поводу неуместности Фединого toggle() в данном коде вопросов нет, надеюсь? Ок.
Сразу ответ: в этом конкретном случае ни скобки ни u не нужны. "Но есть один нюанс!" ;))
Это очень правильный подход - всегда ставить скобки и явное указание типа константы в макросах.
Макросы, в отличии от констант и константных выражений не позволяют указать тип иным способом. Макрос подставляется просто графически, как есть. Сколько уже тут было "вычислителей" времени в макросах с криками: "Памагити ниработаит!"? Так вот явное указание типа не меняет размер или скорость кода, но делает его читаемым и легко сопроводжаемым. То же касается скобок. Ставь их вообще всегда, не задумываясь, иначе будет, как в эпическом фейле Архата с его макросом, который работал ТОЛЬКО потому, что Архат, по дурости, скобки не поставил. ;)))
То есть скобки и "u" - это просто полезные привычки, как комментарии, расстановка фигурных скобок, скобки вокруг единственного оператора в if, while, for и прочее. Указывать на это, как на ошибку - высокомерие, больше похожее на дурость, уж прости.
Ух ты! Да, получилось не красиво. nibelung, я извиняюсь. По трезвому выглядит совсем иначе.(
Изначально еще хотел написать о избыточности явного приведения разности двух байт к типу uint8_t - но подумал, что сам, наверно, написал бы так же - просто на автомате, чтобы не задумыватся о том, какой тип тут примет компилятор.
Вот это, кстати, интересное замечание. Написал так, именно на автомате. Потом убрал приведение типа, ибо выглядит немного громоздко. Убедился, что компилятор, ожидаемо, ошибся. И вернул приведение типа на место.
Компилятор ошибся? - он у вас китайский. наверно...
проверим? - первое условие - без приведения типа, второе - с оным.
01
#define INTERVAL1 23
02
03
void
setup
() {
04
Serial
.begin(115200);
05
}
06
07
void
loop
() {
08
static
uint8_t clk1 = 0, clk2 = 0;
09
static
uint32_t my_millis = 0;
10
uint8_t now = ++my_millis;
11
Serial
.print(now);
12
Serial
.print(
":"
);
13
if
(INTERVAL1 < (now - clk1))
14
{
15
Serial
.print(
"1"
);
16
}
17
else
Serial
.print(
"0"
);
18
19
Serial
.print(
":"
);
20
if
(INTERVAL1 < (uint8_t)(now - clk1))
21
{
22
Serial
.println(
"1"
);
23
}
24
else
Serial
.println(
"0"
);
25
}
результат
001
0:0:0
002
1:0:0
003
2:0:0
004
3:0:0
005
4:0:0
006
5:0:0
007
6:0:0
008
7:0:0
009
8:0:0
010
9:0:0
011
10:0:0
012
11:0:0
013
12:0:0
014
13:0:0
015
14:0:0
016
15:0:0
017
16:0:0
018
17:0:0
019
18:0:0
020
19:0:0
021
20:0:0
022
21:0:0
023
22:0:0
024
23:0:0
025
24:1:1
026
25:1:1
027
26:1:1
028
27:1:1
029
28:1:1
030
29:1:1
031
30:1:1
032
31:1:1
033
32:1:1
034
33:1:1
035
34:1:1
036
35:1:1
037
36:1:1
038
37:1:1
039
38:1:1
040
39:1:1
041
40:1:1
042
41:1:1
043
42:1:1
044
43:1:1
045
44:1:1
046
45:1:1
047
46:1:1
048
47:1:1
049
48:1:1
050
49:1:1
051
50:1:1
052
51:1:1
053
52:1:1
054
53:1:1
055
54:1:1
056
55:1:1
057
56:1:1
058
57:1:1
059
58:1:1
060
59:1:1
061
60:1:1
062
61:1:1
063
62:1:1
064
63:1:1
065
64:1:1
066
65:1:1
067
66:1:1
068
67:1:1
069
68:1:1
070
69:1:1
071
70:1:1
072
71:1:1
073
72:1:1
074
73:1:1
075
74:1:1
076
75:1:1
077
76:1:1
078
77:1:1
079
78:1:1
080
79:1:1
081
80:1:1
082
81:1:1
083
82:1:1
084
83:1:1
085
84:1:1
086
85:1:1
087
86:1:1
088
87:1:1
089
88:1:1
090
89:1:1
091
90:1:1
092
91:1:1
093
92:1:1
094
93:1:1
095
94:1:1
096
95:1:1
097
96:1:1
098
97:1:1
099
98:1:1
100
99:1:1
101
100:1:1
102
101:1:1
103
102:1:1
104
103:1:1
105
104:1:1
106
105:1:1
107
106:1:1
108
107:1:1
109
108:1:1
110
109:1:1
111
110:1:1
112
111:1:1
113
112:1:1
114
113:1:1
115
114:1:1
116
115:1:1
117
116:1:1
118
117:1:1
119
118:1:1
120
119:1:1
121
120:1:1
122
121:1:1
123
122:1:1
124
123:1:1
125
124:1:1
126
125:1:1
127
126:1:1
128
127:1:1
129
128:1:1
130
129:1:1
131
130:1:1
132
131:1:1
133
132:1:1
134
133:1:1
135
134:1:1
136
135:1:1
137
136:1:1
138
137:1:1
139
138:1:1
140
139:1:1
141
140:1:1
142
141:1:1
143
142:1:1
144
143:1:1
145
144:1:1
146
145:1:1
147
146:1:1
148
147:1:1
149
148:1:1
150
149:1:1
151
150:1:1
152
151:1:1
153
152:1:1
154
153:1:1
155
154:1:1
156
155:1:1
157
156:1:1
158
157:1:1
159
158:1:1
160
159:1:1
161
160:1:1
162
161:1:1
163
162:1:1
164
163:1:1
165
164:1:1
166
165:1:1
167
166:1:1
168
167:1:1
169
168:1:1
170
169:1:1
171
170:1:1
172
171:1:1
173
172:1:1
174
173:1:1
175
174:1:1
176
175:1:1
177
176:1:1
178
177:1:1
179
178:1:1
180
179:1:1
181
180:1:1
182
181:1:1
183
182:1:1
184
183:1:1
185
184:1:1
186
185:1:1
187
186:1:1
188
187:1:1
189
188:1:1
190
189:1:1
191
190:1:1
192
191:1:1
193
192:1:1
194
193:1:1
195
194:1:1
196
195:1:1
197
196:1:1
198
197:1:1
199
198:1:1
200
199:1:1
201
200:1:1
202
201:1:1
203
202:1:1
204
203:1:1
205
204:1:1
206
205:1:1
207
206:1:1
208
207:1:1
209
208:1:1
210
209:1:1
211
210:1:1
212
211:1:1
213
212:1:1
214
213:1:1
215
214:1:1
216
215:1:1
217
216:1:1
218
217:1:1
219
218:1:1
220
219:1:1
221
220:1:1
222
221:1:1
223
222:1:1
224
223:1:1
225
224:1:1
226
225:1:1
227
226:1:1
228
227:1:1
229
228:1:1
230
229:1:1
231
230:1:1
232
231:1:1
233
232:1:1
234
233:1:1
235
234:1:1
236
235:1:1
237
236:1:1
238
237:1:1
239
238:1:1
240
239:1:1
241
240:1:1
242
241:1:1
243
242:1:1
244
243:1:1
245
244:1:1
246
245:1:1
247
246:1:1
248
247:1:1
249
248:1:1
250
249:1:1
251
250:1:1
252
251:1:1
253
252:1:1
254
253:1:1
255
254:1:1
256
255:1:1
как видите, результат одинаков на всех возможных значениях
Green, я тоже немного погорячился, Простите если обидел.
То есть скобки и "u" - это просто полезные привычки, как комментарии, расстановка фигурных скобок, скобки вокруг единственного оператора в if, while, for и прочее.
с этим согласен. Но это как раз те самые замечания "вообще", которых я просил избежать. В конкретном коде эти элементы не обязательны, согласен? и потому Грин не так уж неправ - и уж точно его не за что было обвинять в "беграмотности".
А если рассматривать вообще :) - то подавать свой элементарный код как что-то, "отлитое в бронзе", где уже нельзя поправить ни одну букву - вот это как раз глупость и заносчивость...
Изначально еще хотел написать о избыточности явного приведения разности двух байт к типу uint8_t - но подумал, что сам, наверно, написал бы так же - просто на автомате, чтобы не задумыватся о том, какой тип тут примет компилятор.
Вот это, кстати, интересное замечание. Написал так, именно на автомате. Потом убрал приведение типа, ибо выглядит немного громоздко. Убедился, что компилятор, ожидаемо, ошибся. И вернул приведение типа на место.
Компилятор ошибся? - он у вас китайский. наверно...
проверим? - первое условие - без приведения типа, второе - с оным.
01
#define INTERVAL1 23
02
03
void
setup
() {
04
Serial
.begin(115200);
05
}
06
07
void
loop
() {
08
static
uint8_t clk1 = 0, clk2 = 0;
09
static
uint32_t my_millis = 0;
10
uint8_t now = ++my_millis;
11
Serial
.print(now);
12
Serial
.print(
":"
);
13
if
(INTERVAL1 < (now - clk1))
14
{
15
Serial
.print(
"1"
);
16
}
17
else
Serial
.print(
"0"
);
18
19
Serial
.print(
":"
);
20
if
(INTERVAL1 < (uint8_t)(now - clk1))
21
{
22
Serial
.println(
"1"
);
23
}
24
else
Serial
.println(
"0"
);
25
}
результат
001
0:0:0
002
1:0:0
003
2:0:0
004
3:0:0
005
4:0:0
006
5:0:0
007
6:0:0
008
7:0:0
009
8:0:0
010
9:0:0
011
10:0:0
012
11:0:0
013
12:0:0
014
13:0:0
015
14:0:0
016
15:0:0
017
16:0:0
018
17:0:0
019
18:0:0
020
19:0:0
021
20:0:0
022
21:0:0
023
22:0:0
024
23:0:0
025
24:1:1
026
25:1:1
027
26:1:1
028
27:1:1
029
28:1:1
030
29:1:1
031
30:1:1
032
31:1:1
033
32:1:1
034
33:1:1
035
34:1:1
036
35:1:1
037
36:1:1
038
37:1:1
039
38:1:1
040
39:1:1
041
40:1:1
042
41:1:1
043
42:1:1
044
43:1:1
045
44:1:1
046
45:1:1
047
46:1:1
048
47:1:1
049
48:1:1
050
49:1:1
051
50:1:1
052
51:1:1
053
52:1:1
054
53:1:1
055
54:1:1
056
55:1:1
057
56:1:1
058
57:1:1
059
58:1:1
060
59:1:1
061
60:1:1
062
61:1:1
063
62:1:1
064
63:1:1
065
64:1:1
066
65:1:1
067
66:1:1
068
67:1:1
069
68:1:1
070
69:1:1
071
70:1:1
072
71:1:1
073
72:1:1
074
73:1:1
075
74:1:1
076
75:1:1
077
76:1:1
078
77:1:1
079
78:1:1
080
79:1:1
081
80:1:1
082
81:1:1
083
82:1:1
084
83:1:1
085
84:1:1
086
85:1:1
087
86:1:1
088
87:1:1
089
88:1:1
090
89:1:1
091
90:1:1
092
91:1:1
093
92:1:1
094
93:1:1
095
94:1:1
096
95:1:1
097
96:1:1
098
97:1:1
099
98:1:1
100
99:1:1
101
100:1:1
102
101:1:1
103
102:1:1
104
103:1:1
105
104:1:1
106
105:1:1
107
106:1:1
108
107:1:1
109
108:1:1
110
109:1:1
111
110:1:1
112
111:1:1
113
112:1:1
114
113:1:1
115
114:1:1
116
115:1:1
117
116:1:1
118
117:1:1
119
118:1:1
120
119:1:1
121
120:1:1
122
121:1:1
123
122:1:1
124
123:1:1
125
124:1:1
126
125:1:1
127
126:1:1
128
127:1:1
129
128:1:1
130
129:1:1
131
130:1:1
132
131:1:1
133
132:1:1
134
133:1:1
135
134:1:1
136
135:1:1
137
136:1:1
138
137:1:1
139
138:1:1
140
139:1:1
141
140:1:1
142
141:1:1
143
142:1:1
144
143:1:1
145
144:1:1
146
145:1:1
147
146:1:1
148
147:1:1
149
148:1:1
150
149:1:1
151
150:1:1
152
151:1:1
153
152:1:1
154
153:1:1
155
154:1:1
156
155:1:1
157
156:1:1
158
157:1:1
159
158:1:1
160
159:1:1
161
160:1:1
162
161:1:1
163
162:1:1
164
163:1:1
165
164:1:1
166
165:1:1
167
166:1:1
168
167:1:1
169
168:1:1
170
169:1:1
171
170:1:1
172
171:1:1
173
172:1:1
174
173:1:1
175
174:1:1
176
175:1:1
177
176:1:1
178
177:1:1
179
178:1:1
180
179:1:1
181
180:1:1
182
181:1:1
183
182:1:1
184
183:1:1
185
184:1:1
186
185:1:1
187
186:1:1
188
187:1:1
189
188:1:1
190
189:1:1
191
190:1:1
192
191:1:1
193
192:1:1
194
193:1:1
195
194:1:1
196
195:1:1
197
196:1:1
198
197:1:1
199
198:1:1
200
199:1:1
201
200:1:1
202
201:1:1
203
202:1:1
204
203:1:1
205
204:1:1
206
205:1:1
207
206:1:1
208
207:1:1
209
208:1:1
210
209:1:1
211
210:1:1
212
211:1:1
213
212:1:1
214
213:1:1
215
214:1:1
216
215:1:1
217
216:1:1
218
217:1:1
219
218:1:1
220
219:1:1
221
220:1:1
222
221:1:1
223
222:1:1
224
223:1:1
225
224:1:1
226
225:1:1
227
226:1:1
228
227:1:1
229
228:1:1
230
229:1:1
231
230:1:1
232
231:1:1
233
232:1:1
234
233:1:1
235
234:1:1
236
235:1:1
237
236:1:1
238
237:1:1
239
238:1:1
240
239:1:1
241
240:1:1
242
241:1:1
243
242:1:1
244
243:1:1
245
244:1:1
246
245:1:1
247
246:1:1
248
247:1:1
249
248:1:1
250
249:1:1
251
250:1:1
252
251:1:1
253
252:1:1
254
253:1:1
255
254:1:1
256
255:1:1
как видите, результат одинаков на всех возможных значениях
Так уж и "на всех возможных значениях"?
"clk1" вы менять поленились, а ошибки проявляются, когда происходит переполнение.
Так уж и "на всех возможных значениях"?
"clk1" вы менять поленились, а ошибки проявляются, когда происходит переполнение.
Свою точку зрения кодом я подтвердил.
Если не согласны - давайте сделаем так. Вы выкладываете коротенький код, который демонстрирует, что с приведением типа и без него условие if формирует разный результат - тогда и обсудим.
Немного поправил ваш код.
01
#define INTERVAL1 23
02
03
void
setup
() {
04
Serial
.begin(115200);
05
}
06
07
void
loop
() {
08
static
uint8_t clk1 = 100, clk2 = 0;
09
static
uint32_t my_millis = 0;
10
uint8_t now = ++my_millis;
11
Serial
.print(now);
12
Serial
.print(
":"
);
13
if
(INTERVAL1 < (now - clk1))
14
{
15
Serial
.print(
"1"
);
16
}
17
else
Serial
.print(
"0"
);
18
19
Serial
.print(
":"
);
20
if
(INTERVAL1 < (uint8_t)(now - clk1))
21
{
22
Serial
.println(
"1"
);
23
}
24
else
Serial
.println(
"0"
);
25
}
разница совсем небольшая, только clk1 инициализировал отличным от нуля значением.
а вот вывод
001
0:0:1
002
1:0:1
003
2:0:1
004
3:0:1
005
4:0:1
006
5:0:1
007
6:0:1
008
7:0:1
009
8:0:1
010
9:0:1
011
10:0:1
012
11:0:1
013
12:0:1
014
13:0:1
015
14:0:1
016
15:0:1
017
16:0:1
018
17:0:1
019
18:0:1
020
19:0:1
021
20:0:1
022
21:0:1
023
22:0:1
024
23:0:1
025
24:0:1
026
25:0:1
027
26:0:1
028
27:0:1
029
28:0:1
030
29:0:1
031
30:0:1
032
31:0:1
033
32:0:1
034
33:0:1
035
34:0:1
036
35:0:1
037
36:0:1
038
37:0:1
039
38:0:1
040
39:0:1
041
40:0:1
042
41:0:1
043
42:0:1
044
43:0:1
045
44:0:1
046
45:0:1
047
46:0:1
048
47:0:1
049
48:0:1
050
49:0:1
051
50:0:1
052
51:0:1
053
52:0:1
054
53:0:1
055
54:0:1
056
55:0:1
057
56:0:1
058
57:0:1
059
58:0:1
060
59:0:1
061
60:0:1
062
61:0:1
063
62:0:1
064
63:0:1
065
64:0:1
066
65:0:1
067
66:0:1
068
67:0:1
069
68:0:1
070
69:0:1
071
70:0:1
072
71:0:1
073
72:0:1
074
73:0:1
075
74:0:1
076
75:0:1
077
76:0:1
078
77:0:1
079
78:0:1
080
79:0:1
081
80:0:1
082
81:0:1
083
82:0:1
084
83:0:1
085
84:0:1
086
85:0:1
087
86:0:1
088
87:0:1
089
88:0:1
090
89:0:1
091
90:0:1
092
91:0:1
093
92:0:1
094
93:0:1
095
94:0:1
096
95:0:1
097
96:0:1
098
97:0:1
099
98:0:1
100
99:0:1
101
100:0:0
102
101:0:0
103
102:0:0
104
103:0:0
105
104:0:0
106
105:0:0
107
106:0:0
108
107:0:0
109
108:0:0
110
109:0:0
111
110:0:0
112
111:0:0
113
112:0:0
114
113:0:0
115
114:0:0
116
115:0:0
117
116:0:0
118
117:0:0
119
118:0:0
120
119:0:0
121
120:0:0
122
121:0:0
123
122:0:0
124
123:0:0
125
124:1:1
126
125:1:1
127
126:1:1
128
127:1:1
129
128:1:1
130
129:1:1
131
130:1:1
132
131:1:1
133
132:1:1
134
133:1:1
135
134:1:1
136
135:1:1
137
136:1:1
138
137:1:1
139
138:1:1
140
139:1:1
141
140:1:1
142
141:1:1
143
142:1:1
144
143:1:1
145
144:1:1
146
145:1:1
147
146:1:1
148
147:1:1
149
148:1:1
150
149:1:1
151
150:1:1
152
151:1:1
153
152:1:1
154
153:1:1
155
154:1:1
156
155:1:1
157
156:1:1
158
157:1:1
159
158:1:1
160
159:1:1
161
160:1:1
162
161:1:1
163
162:1:1
164
163:1:1
165
164:1:1
166
165:1:1
167
166:1:1
168
167:1:1
169
168:1:1
170
169:1:1
171
170:1:1
172
171:1:1
173
172:1:1
174
173:1:1
175
174:1:1
176
175:1:1
177
176:1:1
178
177:1:1
179
178:1:1
180
179:1:1
181
180:1:1
182
181:1:1
183
182:1:1
184
183:1:1
185
184:1:1
186
185:1:1
187
186:1:1
188
187:1:1
189
188:1:1
190
189:1:1
191
190:1:1
192
191:1:1
193
192:1:1
194
193:1:1
195
194:1:1
196
195:1:1
197
196:1:1
198
197:1:1
199
198:1:1
200
199:1:1
201
200:1:1
202
201:1:1
203
202:1:1
204
203:1:1
205
204:1:1
206
205:1:1
207
206:1:1
208
207:1:1
209
208:1:1
210
209:1:1
211
210:1:1
212
211:1:1
213
212:1:1
214
213:1:1
215
214:1:1
216
215:1:1
217
216:1:1
218
217:1:1
219
218:1:1
220
219:1:1
221
220:1:1
222
221:1:1
223
222:1:1
224
223:1:1
225
224:1:1
226
225:1:1
227
226:1:1
228
227:1:1
229
228:1:1
230
229:1:1
231
230:1:1
232
231:1:1
233
232:1:1
234
233:1:1
235
234:1:1
236
235:1:1
237
236:1:1
238
237:1:1
239
238:1:1
240
239:1:1
241
240:1:1
242
241:1:1
243
242:1:1
244
243:1:1
245
244:1:1
246
245:1:1
247
246:1:1
248
247:1:1
249
248:1:1
250
249:1:1
251
250:1:1
252
251:1:1
253
252:1:1
254
253:1:1
255
254:1:1
256
255:1:1
как видите не везде результат одинаков.
ок, очко в вашу пользу
ок, очко в вашу пользу
Упрямый, но честный! ;))
Это же история, как раз из той области, в которой был мой срач с Андриано. Неявное преобразование между знаковым и беззнаковым. Если не поставить явное преобразование, то будут эти самые грабли. Как же можно забыть такую тему? ;))))
Код на интерференции двух волн не элементарный, а красивый, признай. Много тут новичков, способных выдать такое?
И нормально оформленное. Поправить "ради красоты" там можно только строчку:
1
digitalWrite(LED, ((0 == led_state) ? LOW : HIGH));
заменив на:
1
digitalWrite(LED, led_state ? HIGH : LOW);
или просто
1
digitalWrite(LED, led_state );
;))))))
Я намекал на такое. Хотя знаю, что Влад это не приветствует.
01
#define LED LED_BUILTIN
02
#define INTERVAL1 23
03
#define INTERVAL2 24
04
#define toggle(x) digitalWrite(x, !digitalRead(x))
05
06
void
setup
() {
07
pinMode (LED, OUTPUT);
08
}
09
10
void
loop
() {
11
static
uint8_t clk1, clk2;
12
13
uint8_t now = millis();
14
if
((uint8_t)(now - clk1) > INTERVAL1) {
15
clk1 += INTERVAL1;
16
toggle(LED);
17
}
18
if
((uint8_t)(now - clk2) > INTERVAL2) {
19
clk2 += INTERVAL2;
20
toggle(LED);
21
}
22
}
Я намекал на такое. Хотя знаю, что Влад это не приветствует.
01
#define LED LED_BUILTIN
02
#define INTERVAL1 23
03
#define INTERVAL2 24
04
#define toggle(x) digitalWrite(x, !digitalRead(x))
05
06
void
setup
() {
07
pinMode (LED, OUTPUT);
08
}
09
10
void
loop
() {
11
static
uint8_t clk1, clk2;
12
13
uint8_t now = millis();
14
if
((uint8_t)(now - clk1) > INTERVAL1) {
15
clk1 += INTERVAL1;
16
toggle(LED);
17
}
18
if
((uint8_t)(now - clk2) > INTERVAL2) {
19
clk2 += INTERVAL2;
20
toggle(LED);
21
}
22
}
Такое тоже работать будет, но есть маааленький косячок.
Когда условия по INTERVAL1 и INTERVAL2 выполнятся на одном проходе Loop, у вас на диоде получится очень короткий импульс, а по задумке его там быть не должно.
Я намекал на такое. Хотя знаю, что Влад это не приветствует.
01
#define LED LED_BUILTIN
02
#define INTERVAL1 23
03
#define INTERVAL2 24
04
#define toggle(x) digitalWrite(x, !digitalRead(x))
05
06
void
setup
() {
07
pinMode (LED, OUTPUT);
08
}
09
10
void
loop
() {
11
static
uint8_t clk1, clk2;
12
13
uint8_t now = millis();
14
if
((uint8_t)(now - clk1) > INTERVAL1) {
15
clk1 += INTERVAL1;
16
toggle(LED);
17
}
18
if
((uint8_t)(now - clk2) > INTERVAL2) {
19
clk2 += INTERVAL2;
20
toggle(LED);
21
}
22
}
Такое тоже работать будет, но есть маааленький косячок.
Когда условия по INTERVAL1 и INTERVAL2 выполнятся на одном проходе Loop, у вас на диоде получится очень короткий импульс, а по задумке его там быть не должно.
Вот именно про это я написал, когда сказал, что Федин toggle() неуместен.
И еще
1
void
loop
() {
2
static
uint8_t clk1, clk2;
Это, все таки, объявление глобальных переменных с областью видимости, ограниченной, функцией Loop. Их желательно явно инициализировать.
И еще
1
void
loop
() {
2
static
uint8_t clk1, clk2;
Это, все таки, объявление глобальных переменных с областью видимости, ограниченной, функцией Loop. Их желательно явно инициализировать.
а тут ты неправ... ;))) хороший тон, но необязательно. Ну и слово "глобальные" совершенно не к месту и не в тему.
Пожалуйста объясните, зачем объявлять переменные локально для проектов на МК. Я понимаю зачем для ББ, но МК? Программа память не экономит. Несколько подпрограмм и так разберуться какие переменные используются, а если про волатильные вспомнить - всё равно приходится глобальными объявлять. На хороший тон не ссылаться. Есть ли какие ни будь другие преимущества? В циклах можно областью видимости обойтись.
И еще
1
void
loop
() {
2
static
uint8_t clk1, clk2;
Это, все таки, объявление глобальных переменных с областью видимости, ограниченной, функцией Loop. Их желательно явно инициализировать.
а тут ты неправ... ;))) хороший тон, но необязательно. Ну и слово "глобальные" совершенно не к месту и не в тему.
Дык я и написал "желательно", а не "обязательно". Именно хороший тон.
По поводу слова "глобальный" спорить не буду.
staticheskie-lokalnye-peremennye
"Когда static применяется к локальной переменной, это приводит к тому, что компилятор создает долговременную область для хранения переменной почти таким же способом, как это делается для глобальной переменной. Ключевое различие между статической локальной и глобальной переменными заключается в том, что статическая локальная переменная остается известной только в том блоке, в котором она была объявлена. Проще говоря, статическая локальная переменная - это локальная переменная, сохраняющая свое значение между вызовами функций."
Пожалуйста объясните, зачем объявлять переменные локально для проектов на МК. Я понимаю зачем для ББ, но МК? Программа память не экономит. Несколько подпрограмм и так разберуться какие переменные используются, а если про волатильные вспомнить - всё равно приходится глобальными объявлять. На хороший тон не ссылаться. Есть ли какие ни будь другие преимущества? В циклах можно областью видимости обойтись.
Ни за чем, кроме хорошего тона и удобства сопровождения. Ничто так не кричит об "авторе-чайнике", как обилие глобалов. Даже сам, через (для меня) два-три месяца, уже не помнишь, что и для чего заведено. Объявления статиков там, где они используются, дает возможность вспомнить подробности. Это не говоря про совместную разработку. Тут даже комментировать нечего.
Короче так: если в программе много глобальных переменных - лучше не платить такому автору вообще! ;))) Ну я бы не стал и клиентам бы не посоветовал! ;))
"Когда static применяется к локальной переменной, это приводит к тому, что компилятор создает долговременную область для хранения переменной почти таким же способом, как это делается для глобальной переменной. Ключевое различие между статической локальной и глобальной переменными заключается в том, что статическая локальная переменная остается известной только в том блоке, в котором она была объявлена. Проще говоря, статическая локальная переменная - это локальная переменная, сохраняющая свое значение между вызовами функций."
Это ты дискуссию со мной предлагаешь? ;)) Очень мило, с твоей стороны, но я, пожалуй, воздержусь. ;))
"Когда static применяется к локальной переменной, это приводит к тому, что компилятор создает долговременную область для хранения переменной почти таким же способом, как это делается для глобальной переменной. Ключевое различие между статической локальной и глобальной переменными заключается в том, что статическая локальная переменная остается известной только в том блоке, в котором она была объявлена. Проще говоря, статическая локальная переменная - это локальная переменная, сохраняющая свое значение между вызовами функций."
Это ты дискуссию со мной предлагаешь? ;)) Очень мило, с твоей стороны, но я, пожалуй, воздержусь. ;))
Завсегда приятно поговорить с умным и образованным человеком ;)) Но нет, я же признал, что слово "глобальные" там не совсем в тему.
Это ты дискуссию со мной предлагаешь? ;)) Очень мило, с твоей стороны, но я, пожалуй, воздержусь. ;))
какой-то ты, Влад, сегодня, не такой :) Не заболел? :) не чувствуется привычной бодрости в общении с новичками :)
Это ты дискуссию со мной предлагаешь? ;)) Очень мило, с твоей стороны, но я, пожалуй, воздержусь. ;))
какой-то ты, Влад, сегодня, не такой :) Не заболел? :) не чувствуется привычной бодрости в общении с новичками :)
последствия Короны сказываются и, как показала практика у каждого они свои ...
таки и не понял почему всё таки не?:
1
static
bool
led_state = 0;
таки и не понял почему всё таки не?:
1
static
bool
led_state = 0;
Да можно и так. Ошибкой не будет использование любого варианта. Так что, это из разряда личных предпочтений.
таки и не понял почему всё таки не?:
1
static
bool
led_state = 0;
Да можно и так. Ошибкой не будет использование любого варианта. Так что, это из разряда личных предпочтений.
я бы не был столь категоричным, если тип переменной bool, то это даёт экономию памяти программ 2 байта и памяти ОЗУ байт... если применять не битовую математику для изменения значения переменной...точнее знающие подскажут
таки и не понял почему всё таки не?:
1
static
bool
led_state = 0;
Да можно и так. Ошибкой не будет использование любого варианта. Так что, это из разряда личных предпочтений.
я бы не был столь категоричным, если тип переменной bool, то это даёт экономию памяти программ 2 байта и памяти ОЗУ байт... если применять не битовую математику для изменения значения переменной...точнее знающие подскажут
Я бы с вами согласился, если бы тип int менялся на bool. Но, в данном случае, меняется uint8_t на bool. Оба типа размерностью в один байт, так что экономии не будет.
Если рассматривать данную функцию с точки зрения практического применения, то очевидно, что для нормальной работы она требует стабильного короткого цикла и вызов ее в основном лупе не всегда приведет к корректной её работе. Например в блинке с делеями она работать не будет. Выход - разместить функцию в прерывании таймера, например вариант в TMR0:
01
#define LED_IN PB5 //LED_BUILTIN
02
03
void
setup
() {
04
cli();
//stop interrupts
05
OCR0A = 0;
06
TIMSK0 |= _BV(OCIE0A);
//Разрешить прерывание Timer0 по совпадению
07
sei();
//allow interrupts
08
DDRB |= _BV(LED_IN);
// вывод на выход
09
}
10
11
void
loop
() {
12
13
}
14
//************************InterruptTMR0****************************
15
ISR(TIMER0_COMPA_vect) {
16
17
#define INTERVAL1 23
18
#define INTERVAL2 24
19
static
uint8_t clk1 = 0,
20
clk2 = 0,
21
now = 0,
22
led_state = 0;
23
24
if
((uint8_t)(++now - clk1) > INTERVAL1)
25
{
26
clk1 += INTERVAL1;
27
led_state ^= 1;
28
}
29
30
if
((uint8_t)(now - clk2) > INTERVAL2)
31
{
32
clk2 += INTERVAL2;
33
led_state ^= 1;
34
}
35
//digitalWrite(LED, led_state);
36
(led_state)? (PORTB |= _BV(LED_IN)): (PORTB &= ~_BV(LED_IN));
37
38
}