Есть GSM модуль SIM800L. Если специальным образом сформировать сообщение, то можно отправить sms на кириллице. Как формируется узнал тут: http://www.edgemodem.ru/forum/viewtopic.php?f=8&t=901
Цитирую:
01 | Само сообщение состоит из HEX-последовательности, прописанной ASCII-символами (0..9,A..F). |
02 | Пример - надо отправить сообщение абоненту +79212345678 и в нем написать 'Привет' . |
03 | ВНИМАНИЕ! РЕЧЬ ИДЕТ О ТОМ, КАК ЭТО СДЕЛАТЬ ПРОГРАММНО (или через HyperTerminal), А НЕ С ПОМОЩЬЮ, например, SiMoCo. Т.е. ручками. |
05 | 1. Берем бумажку и составляем последовательность: |
06 | 00 - всегда - это означает, что телефон/модем берет адрес сервис-центра SMS из Симки |
08 | 00 - указывает, что в качество отправителя будет указан собственный номер тел/модема |
09 | 0B - длина цифр телефонного номера = 11(дес) |
10 | 91 - указывает на интернациональный формат тел. номера (+7...) |
11 | 9712325476F8 - номер адресата, которому отправляем SMS |
13 | 1. в начале записываем номер (на другую бумажку) |
14 | 2. проверяем, четное ли количество цифр и если нет (как у нас - 11), добавляем в конце "F" |
15 | 3. переставляем каждые две цифры местами - получаем результат |
20 | 00 - идентификатор протокола |
21 | 08 - формат кодирования сообщения - в нашем случае - USC2 |
22 | 17 - время действия SMS |
24 | 0-143: (код + 1)*5минут - наш случай ((17H = 23дес) + 1)*5=120минут=2часа |
25 | 144-167: 12 часов + (код - 143)*30минут |
26 | 168-196: (код - 166) * 1день |
27 | 197-255: (код - 192) * 1неделя |
28 | 0C - количество байт в сообщении = количество символов*2, т.к. USC2 |
35 | Коды символов соответствуют нормальному Unicode. Можно посмотреть, например, встроенную программу "Таблица символов" , выбрать шрифт, например Arial, прокрутить вниз до начала кириллицы и посмотреть их коды (отображаются в HEX-виде внизу окна). |
37 | 2. Даем команду тел/модему |
38 | AT+CMGF=0 - включаем режим PDU |
39 | AT+CMGS=26 - длина байтов сообщения (по 2 цифры), без учета первого нулевого байта |
40 | >0011000B919712325476F80008170C041F04400438043204350442Ctrl+Z |
41 | +CMGS: 13 - это уже ответ модема |
45 | И еще. Тот же симоко, иногда почему-то, вставляет вместо первого нуля явный адрес сервис центра - |
46 | 07919712999090F0 - понятно (см. выше), что это телефон 79219909090. Первый байт - длина последовательности (без него самого). Вроде все правильно, но MC35 возвращает ERROR. Причину не знаю. |
А теперь нужно чтобы ардуино могла сама слать таике смс. Причём чтоб могда переводить в нужную кодировку.
Мне нужно отправлять смс по хозяйству вида: "Проникновение в гараж", "Напряжение в сети 200 Вольт", "Температура котла снизилась до 40 градусов" и т.д. Казалось бы нет проблем, заранее сформировал сам, а в ардуино вбить как переменную всё сообщение. Но так не получится, потому что служебные символы, которые в заголовке сообщения, должны учитываться, а сообщение содержит переменные. Получается, что заранее никак не просчитать. Поэтому нужно как-то реализовать на ардуино алгоритм, который мог бы в итоге составить смс на кириллице и отправить его. Я просмотрел множество библиотек, но не нашёл такого функционала. Может кто встречал нужный мне кусок кода? Или может для кого-то сделать этот код - дело двух минут, и он поделится им с общественностью?
Вариант отправлять тексты транслитом не проходит, только кириллица ?
Вариант отправлять тексты транслитом не проходит, только кириллица ?
Очень желательно кириллицу. Я уже сделал систему различных оповещений для деда и бабушки на транслите. Им совершенно не понятно что на транслите написано, он их просто пугает.
А если так, как описано здесь http://forum.amperka.ru/threads/gprs-shield-v-2-arduino-uno.2955/#post-25495 ?
Правда с переменными сложнее будет.
А эту http://users.skynet.be/moustic/PduEncoder.zip библиотеку пробовали ?
А это https://sites.google.com/site/marthalprojects/home/arduino/arduino-sends-SMS читали ?
Спасибо! Я это изучу.
Sirocco, а проблема в чём? Вроде всё подробно описано - просто делай как написано и всё. Вы не можете запрограммировать то, что у Вас описано или можете, но оно не работает? В чём беда-то?
Sirocco, а проблема в чём? Вроде всё подробно описано - просто делай как написано и всё. Вы не можете запрограммировать то, что у Вас описано или можете, но оно не работает? В чём беда-то?
Беда была в последней части этой статьи: https://sites.google.com/site/marthalprojects/home/arduino/arduino-sends-SMS
Пока нет времени попробовать, но похоже это то, что нужно.
Ничего не понял, ну, ладно, Вам виднее.
Кое как сделал рабочий скетч отправки СМС на кириллице с GSM sim800L ну или sim900 тоже будет работать. Для исходящих СМС с модуля используется формат PDU. Принимаются СМС в обычном текстовом режиме. Перед заливкой в ардуино скетч нужно скопировать в новое окно (в новый скетч) и не сохраняя на компе залить в ардуино. Это нужно так как имеется косяк с кодировками кириллицы.
001
#include <EEPROM.h>
002
// для GSM модуля *********************
003
#include <SoftwareSerial.h>
004
SoftwareSerial mySerial(7, 8);
//Rx, Tx На этот порт GSM модуль
005
String currStr =
""
;
006
007
String TelNumber1 =
"000000000000"
;
008
009
String TelNumber2 =
"000000000000"
;
010
011
String BufferNumber =
"000000000000"
;
012
String DelSMS =
"AT+CMGDA=\"DEL ALL\"\r"
;
013
String phone_nr=
""
;
014
String message=
""
;
015
bool
SaveNumber2 = 0;
// флаг, когда необходима запись номера#2, он true
016
017
int
isStringMessage = 0;
018
int
KTOzapros = 0;
019
int
KTOreport = 1;
020
021
022
023
// пример переменных, используемых в проекте
024
int
Temp1 =45;
025
int
Temp2 =11;
026
int
Temp3 =20;
027
bool
device = 0;
028
bool
trevoga = 0;
029
bool
alarmSMS =
false
;
030
int
TimeWorkDevice_1 = 10;
031
032
void
setup
() {
033
034
delay (10000);
035
// Serial.begin (9600);
036
// Serial.print ("Restart");
037
mySerial.begin(19200);
038
delay(2000);
039
NastroykaGSM ();
040
041
for
(
int
i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
042
for
(
int
i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);
043
044
}
045
046
void
loop
() {
047
048
if
(trevoga && !alarmSMS) AlarmSMS();
049
readSMS();
050
051
}
052
053
054
void
NastroykaGSM () {
055
mySerial.print(
"AT+CMGF=1\r"
);
//устанавливает текстовый режим смс-сообщения
056
delay(400);
057
mySerial.print(
"AT+IFC=1, 1\r"
);
//устанавливает программный контроль потоком передачи данных
058
delay(400);
059
mySerial.print(
"AT+CPBS=\"SM\"\r"
);
//открывает доступ к данным телефонной книги SIM-карты
060
delay(400);
061
mySerial.print(
"AT+GSMBUSY=1\r"
);
//запрет всех входящих звонков
062
delay(400);
063
mySerial.print(
"AT+CNMI=1,2,2,1,0\r"
);
//включает оповещение о новых сообщениях
064
delay(400);
065
mySerial.print(DelSMS);
// удаляем все смс, ки
066
delay(2000);
067
}
068
069
070
071
void
readSMS()
//_____Цикл чтения входящих СМС-сообщений______________
072
{
073
if
(!mySerial.available())
return
;
074
char
currSymb = mySerial.read();
075
// Serial.print (currSymb);
076
if
(
'\r'
== currSymb)
077
{
078
if
(isStringMessage!=0&&isStringMessage!=10)
//если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
079
{
080
if
(currStr.equalsIgnoreCase(
"ZAPROS"
)) { SMSzapros();}
// Запрос состояния параметров (переменных проекта) по СМС
081
else
if
(currStr.equalsIgnoreCase(
"ZAPROSTEL"
)) { SMSzaprosTEL();}
// Передача сохраненных номеров телефонов пользователей по СМС
082
083
084
085
086
087
088
else
if
(currStr.equalsIgnoreCase(
"device_1-ON"
)) {
if
(!device) {device = 1;
// тут что то включаем по этой команде, если например булевая переменная device - 0 выключена ;
089
if
(isStringMessage == 1) {phone_nr = TelNumber1; }
090
else
if
(isStringMessage == 2) {phone_nr = TelNumber2; }
091
message =
"Устройство_1 ВКЛ"
; EndSMS();}
092
093
else
{
if
(isStringMessage == 1) phone_nr = TelNumber1;
// ничё не делаем, т.к. булевая переменная device - 1 и так включена ;
094
else
if
(isStringMessage == 2) phone_nr = TelNumber2;
095
message =
"Устройство_1 уже было включено"
; EndSMS();}}
096
097
098
else
if
(currStr.equalsIgnoreCase(
"device_1-OFF"
)) {
if
(device) {device = 0;
// тут выключаем устройство, если например булевая переменная Work - 1 включена ;
099
if
(isStringMessage == 1) {phone_nr = TelNumber1; }
100
else
if
(isStringMessage == 2) {phone_nr = TelNumber2; }
101
message =
"Устройство_1 ВЫКЛ"
; EndSMS();}
102
103
else
{
if
(isStringMessage == 1) phone_nr = TelNumber1;
// ничё не делаем, т.к. булевая переменная device - 0 и так выключена ;
104
else
if
(isStringMessage == 2) phone_nr = TelNumber2;
105
message =
"Устройство_1 уже было выключено"
; EndSMS();}}
106
107
108
else
if
(currStr.endsWith(
"min"
)) {TimeWorkDevice_1 = currStr.toInt()*60000UL;
// для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
109
if
(TimeWorkDevice_1>3540000UL) TimeWorkDevice_1 = 3540000UL;
110
if
(TimeWorkDevice_1<=600000UL) TimeWorkDevice_1 = 600000UL;
111
EEPROM.write(1,TimeWorkDevice_1/60000UL);
112
if
(isStringMessage == 1) phone_nr = TelNumber1;
113
else
if
(isStringMessage == 2) phone_nr = TelNumber2;
114
message = (
"Время работы Устройства_1: "
); message+= String (currStr.toInt()); message += (
"мин"
); EndSMS();}
115
116
117
else
if
(currStr.equalsIgnoreCase(
"ResetNumbers"
)) {
if
(isStringMessage == 1) phone_nr = TelNumber1;
118
else
if
(isStringMessage == 2) phone_nr = TelNumber2;
119
message =
"Тел.номера пользователей стерты из памяти"
; EndSMS();
120
TelNumber1 =
"000000000000"
; TelNumber2 =
"000000000000"
;
for
(
int
i=0; i<12; i++) {EEPROM.write (i+10, TelNumber1[i]); EEPROM.write (i+30, TelNumber2[i]); }}
121
122
else
if
(currStr.equalsIgnoreCase(
"WriteNumber2"
)&& isStringMessage == 1) { SaveNumber2 = 1; phone_nr = TelNumber1; message =
"Отправьте любое СМС с номера#2 для его сохранения"
; EndSMS();}
123
124
else
if
(currStr.equalsIgnoreCase(
"Balance"
)) SMSbalance();
125
isStringMessage = 0;
126
}
127
128
129
else
if
(isStringMessage==10){
if
(currStr.equalsIgnoreCase(
"WriteNumber1"
)) { TelNumber1 = BufferNumber;
for
(
int
i=0; i<12; i++) {EEPROM.write (i+10, BufferNumber[i]);}
130
phone_nr = TelNumber1; message =
"Тел. номер #1 сохранен"
; EndSMS();
131
}
132
else
if
(currStr.equalsIgnoreCase(
"ZAPROS"
)) SMSzapros();
133
else
if
(currStr.equalsIgnoreCase(
"ZAPROSTEL"
)) SMSzaprosTEL();
// Передача номеров телефонов пользователей по СМС
134
isStringMessage = 0;
135
136
}
137
138
139
140
141
else
if
(isStringMessage==0) {
if
(TelNumber1!=
"000000000000"
&& !SaveNumber2 && TelNumber1!=
"яяяяяяяяяяяя"
){
142
143
if
(currStr.startsWith(
"+CMT: \""
+TelNumber1)) { isStringMessage = 1; KTOzapros = 1; }
144
else
if
(currStr.startsWith(
"+CMT: \""
+TelNumber2)) { isStringMessage = 2; KTOzapros = 2; }
145
else
if
(currStr.startsWith(
"+CUSD: 0,"
))
//если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса
146
{
147
if
(KTOzapros == 1) phone_nr = TelNumber1;
148
else
if
(KTOzapros == 2) phone_nr = TelNumber2;
149
message = currStr;
150
EndSMS();
151
}
152
}
153
154
else
if
(currStr.startsWith(
"+CMT:"
) && !SaveNumber2) { isStringMessage = 10;
for
(
int
i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];}}
155
else
if
(currStr.startsWith(
"+CMT:"
) && SaveNumber2) {
for
(
int
i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];} TelNumber2 = BufferNumber;
for
(
int
i=0; i<12; i++) {EEPROM.write (i+30, BufferNumber[i]);}
156
phone_nr = TelNumber2; message =
"Ваш номер сохранен в памяти как номер#2"
; EndSMS(); SaveNumber2 = 0; }
157
}
158
159
currStr =
""
;
160
}
161
162
else
if
(
'\n'
!= currSymb) { currStr += String(currSymb);}
163
}
164
165
166
167
168
void
EndSMS ()
169
{
170
171
172
173
String newphone_nr;
174
int
numlength;
175
176
177
mySerial.print(
"AT+CMGF=0\r"
);
178
delay(200);
179
numlength=phone_nr.length()-1;
180
if
(numlength% 2 != 0 ) {
181
phone_nr +=
"F"
; }
182
for
(
int
x = 0; x < numlength; x = x+2){
183
newphone_nr.concat(phone_nr.charAt(x+2));
184
newphone_nr.concat(phone_nr.charAt(x+1));}
185
186
187
188
byte
textbyte[200] = {0};
189
for
(
int
i=0; i<message.length(); i++){ textbyte[i]=
byte
(message[i]); }
190
int
k = 0;
int
n=0;
191
while
( k<(message.length()*2)) {
192
byte
b0 =
byte
(message[k]);
193
if
(b0<128) {textbyte[k+n] = 0;
194
textbyte[k+n+1] = message[k];
195
}
196
197
else
{
198
int
val = b0+0x350;
199
byte
b1 = (
byte
)( val >> 8 );
200
textbyte[k+n] = b1;
201
byte
b2 = (
byte
)val;
202
textbyte[k+n+1] = b2;
203
}
204
k++; n++;
205
}
206
int
pdu_length = 0;
207
int
textlength = message.length()*2;
// text message length: number of characters*7/8
208
// Serial.println ((message.length()*2), HEX);
209
if
((message.length()*2) != 0) {textlength++;}
210
if
(numlength%2 != 0) {
//if the length of phone number was uneven, it now increases by 1 because of the added "F"
211
pdu_length = (7 + (numlength+1)/2 + textlength); }
else
{
//8 bytes of parameters + (length of phonenumber)/2 + number of bytes in the text
212
pdu_length = (7 + numlength/2 + textlength); }
213
214
mySerial.print(
"AT+CMGS="
);
//message will be stored in the mobile phone - AT+CMGS will send it off.
215
// Serial.print("AT+CMGS="); //message will be stored in the mobile phone - AT+CMGS will send it off.
216
mySerial.println(pdu_length);
217
// Serial.println(pdu_length);
218
delay(3000);
219
mySerial.print(
"001100"
);
//these are some parameters which we don't need to bother about
220
// Serial.print("001100"); //these are some parameters which we don't need to bother about
221
if
(numlength<16){
//now we have to send the byte containing the length of the phone number in HEX format
222
mySerial.print(0);
223
// Serial.print(0);
224
}
//the byte in HEX format needs to be 2 characters long; if needed we add a 0 in front, e.g. "C" will become "0C"
225
mySerial.print(numlength,HEX);
226
// Serial.print(numlength,HEX);//length telnr - this time any additional F is not to be considered
227
mySerial.print(
"91"
);
228
// Serial.print("91");//international format of phone number //81 for national format
229
mySerial.print(newphone_nr);
230
// Serial.print(newphone_nr);//now we send the rearranged phone number
231
mySerial.print(
"0008AA"
);
232
// Serial.print("0008AA");//some more parameters
233
if
((message.length()*2)<16){
234
mySerial.print(0);
235
// Serial.print(0);
236
}
//now a byte in HEX format indicating the length of the text. Again the byte needs to be made of 2 characters
237
mySerial.print((message.length()*2),HEX);
238
// Serial.print((message.length()*2),HEX);
239
240
241
for
(
int
i=0; i<(message.length()*2); i++){
242
if
(textbyte[i]<16) {mySerial.print (0);
//Serial.print (0);
243
}
244
mySerial.print (textbyte[i], HEX);}
245
246
247
delay (3000);
248
249
250
251
252
mySerial.println((
char
)26);
// Команда отправки СМС
253
delay(3500);
254
message =
""
;
255
phone_nr =
""
;
256
pdu_length=0;
257
newphone_nr=
""
;
258
numlength=0;
259
260
mySerial.print(DelSMS);
// удаляем все смс, ки
261
delay(2500);
262
mySerial.print(
"AT+CMGF=1\r"
);
263
delay (500);
264
}
265
266
267
268
269
void
SMSzapros()
270
{
271
if
(isStringMessage == 10){
272
phone_nr = BufferNumber;
273
274
message =
"Тел.номер #1 не записан. Управление невозможно!"
;
275
// message+= ("Тел.#1: "); message+=String (TelNumber1); message+="\r\n";
276
// message+= ("Тел.#2: "); message+=String(TelNumber2);
277
}
278
279
else
{
280
if
(isStringMessage == 1) phone_nr = TelNumber1;
281
else
if
(isStringMessage == 2) phone_nr = TelNumber2;
282
283
284
if
(device) message =
"Устройство_1 ВКЛ\r\n"
;
285
else
message =
"Устройство_1 ВЫКЛ\r\n"
;
286
287
if
(trevoga) message += (
"Внимание! Тревога!\r\n"
);
288
289
message +=(
"Температура_1: "
); message += String (Temp1); message +=(
"*C"
);
290
// message +=("Температура_2: "); message += String (Temp2); message +=("*C");
291
// message +=("Температура_3: "); message += String (Temp3); message +=("*C");
292
293
}
294
EndSMS();
295
}
296
297
void
SMSzaprosTEL(){
298
if
(isStringMessage == 1) phone_nr = TelNumber1;
299
else
if
(isStringMessage == 2) phone_nr = TelNumber2;
300
else
if
(isStringMessage == 10) phone_nr = BufferNumber;
301
302
303
message = (
"Тел.#1: "
); message+=String (TelNumber1); message+=
"\r\n"
;
304
message+= (
"Тел.#2: "
); message+=String(TelNumber2);
305
306
EndSMS();
307
}
308
309
310
void
SMSbalance() {
311
mySerial.print(
"AT+CMGF=1\r"
);
312
delay(200);
313
mySerial.println (
"AT+CUSD=1,\"#100#\""
);
314
delay(2000);
315
}
316
317
318
void
AlarmSMS() {
319
phone_nr = TelNumber1;
320
message = (
"Внимание!!! Тревога! Сирена Вкл!"
);
321
EndSMS();
322
phone_nr = TelNumber2;
323
message = (
"Внимание!!! Тревога! Сирена Вкл!"
);
324
EndSMS();
325
alarmSMS =
true
; }
Есть проблема, что большое СМС не получается отправить, т.к. всё сообщение должно записаться в одну строку String и потом перейти в массив байтов . На это видимо не хватает оперативки, и ардуино начивает нехило глючить или перезагружается. Подскажите , какие могут быть пути решения для оптимизации скетча?
Может использовать SD карту для хранения строковых констант и других String ов?
Подскажите , какие могут быть пути решения для оптимизации скетча?
Неизменные строки положить в PROGMEM, от использования String отказаться полностью. перейти на использование C-style char arrays.
Макс. вы уже который раз об этом спрашиваете... Вас видимо, ответы не устраивают. Надеетесь, что кто-то вдруг взмахнет волшебной палочкой и проблемы исчезнут сами собой? :)
конкретно об этом я не справшивал вроде. Про PROGMEM буду читать.
хотел добавить к предыдущему ответу. но не успел - вы уже ответили.
SD карта вам не поможет, потому что прежде чем использовать сохраненные на ней строки, их все равно сначала надо будет скопировать в оперативку. Напротив, ситуация станет только хуже, потому что сама библиотека работы с SD "жрет" память по черному.
ок, SD не вариант.
ПС. Загрузка оперативы глобальными переменными 67%. И это ещё совсем мало команд смс и нет остального чем управляем GSM. Похоже тяжела задачка для меги 328, но будем пробовать ваши варианты
ПС. Загрузка оперативы глобальными переменными 67%.
Есть еще хорошее правило - как можно меньше глобальных переменных. Используйте константы, макросы и локальные переменные.
Похоже тяжела задачка для меги 328
Не скромничайте. Это для Вас тяжёлая задачка, а не для меги 328 :)))
вы мне такими сообщениями весь настрой сбиваете. Клапауция хватает, лучше бы по делу
вы мне такими сообщениями весь настрой сбиваете. Клапауция хватает, лучше бы по делу
я тебе говорил по делу, что ты - глист.
тебе подсказали все возможные варианты решения твоей личной проблемы, но ты - глист, способный потреблять переваренное и добытое кем-то.
А ты не будь занозой в заднице. Проблема не только моя личная. Думаю пользователи форума не прочь овладеть посылкой смс на кириллице, сто процентов кому то ещё пригодится. про глиста ты загнул конечно, дружище. расслабься, я благодарен за предоставленную инфу, нужно время разобраться.
Думаю пользователи форума не прочь овладеть посылкой смс на кириллице, сто процентов кому то ещё пригодится.
под "овладеть" ты, конечно, подразумеваешь, что тебе кто-то притащит готовое или ты найдёшь в тырнетах готовое, но оно у тебя работать не будет и ты будешь возмущаться, что скетч по-дыбильному написан.
так себе представляешь процесс овладения? :D
кончай язвить а, да с моим уровнем пргограммирования нихера путнего не сделать. Но на чужих примерах и пытаюсь учится. У меня только так получается, читая теорию, всё бросить сразу хочется. А так Скил потихоньку качается. Если всё заработет, ничё не вижу плохого в том, что какой-нить чел взял скетч и пользуется. я вроде и не возмущаюсь, т.к. у самого скетчи такие же пока.
всё бросить сразу хочется.
дык ... ото ж :)
лучше бы по делу
А чего по делу? По делу Вы сами себе дано ответили, причём ответили Вы правильно, только ответ Вам не нравится, вот Вы и прячете голову в песок и пудрите мозг себе и нам.
Вот Вы пишете:
Ну??? И дальше чего???
У меня к Вам простой вопрос: нахера? Даю с разбивкой на-хе-ра Вы используете String, а потом преобразуете в char[]? Нахера? Вам память девать некуда? Другого объяснения не вижу.
Да и само использование String - у Вас же не ужас, а ужас-ужас-ужас! Вы выбрали САМЫЕ дорогие операции (типа concat) и юзаете их в хвост и в гриву! Нахера?
Вы читали мою стаьтю про String и память? Читали вообще мои заметки про память? Вот эту, например? Они вель приклеены сверху раздела! Исследовали свою программу MemroyExplorer'ом? Так сделайте это - сами ужаснётесь!
А ведь главное, Вы всё отлично понимаете! Так садитесь и изучайте работу с массивами символов. Объявите слово String матерным и недопустимым в приличном скетче и ... Вы удивитесь как много памяти у Вашего контроллера.
вот так бы сразу, а.
я хотел как проще, подозревал что памяти не хватит, но чтоб так быстро. Понято, перехожу на array char
почитал заметку про String, мой случай))
вопрос про текстовые константы или как там их назвать, используемые с - mySerial.print ("Вот эти строки"). Достаточно ли просто для высвобождения оперативки
1
mySerial.print(
"AT+CMGF=1\r"
);
заменить на
1
mySerial.print(F(
"AT+CMGF=1\r"
));
поможет ли это?
Там по второй ссылке в моём прошлом посте, есть такая программа MemoryExplorer.
Делаете маленький пример со своим строками, запускаете так и эдак и смотрите на состояние памяти в том и в другом случае.
Во-первых получаете ответ на вопрос, а во-вторых привыкаете самостоятельно решать возникающие проблемы.
понял, работаем над собой
поможет ли это?
Макс, Вы меньше спрашивайте, а больше делайте. Пока вы писали это сообщение, я загрузил ваш скетч и заключил "Все эти строки" в макрос F(). И откомпилировал. И сразу увидел, что выигрыш есть, но небольшой. Заняло у меня это действо 8 минут, включая вход в Ардуино и создание нового скетча.
К сожалению, большая часть ваших строк - String - а с ними этот метод не работает. малой кровью не отделаетесь.
Перед заливкой в ардуино скетч нужно скопировать в новое окно (в новый скетч) и не сохраняя на компе залить в ардуино. Это нужно так как имеется косяк с кодировками кириллицы.
Костыль у вас имеется, а не рабочий код, вот и всё. Я вам приводил пример, повторюсь: https://github.com/Porokhnya/GreenhouseProject/blob/master/Main/PDUClasses.h - вот тут объявление всего ДВУХ классов, которые корректно и кодируют (в UCS2), и раскодируют SMS-сообщения в ЛЮБОЙ кодировке. Есть проверка на то, что SMS пришло с правильного номера, чтобы память раскодировкой не насиловать. Рядом валяется файл *.cpp, как это дело подключить к проекту и как юзать - доступно самому-самому джуниору (только вырезать ненужные include в cpp-файле, да чуть подточить, при необходимости). Собственно, эти классы являются некой компиляцией разнородного кода, найденного в сети, плюс - дописанный ручками нужный функционал. И будет вам автоматом SMS на любом языке, не только на кириллице - главное, чтобы строка, которую надо отправить по SMS - была в формате UTF-8, который, как известно, имеет переменную длину кодирования символа, т.е. туда впихуется практически всё, с точки зрения языков (думаю, вам хватит).
А вы непонятный секс с сохранением скетча развели.
А вы непонятный секс с сохранением скетча развели.
Ну, почему непонятный? Как раз понятный :)))
я делал перекодировку просто таблицей соответсвия
1
byte
Rus1251keys[66] = {70, 60, 68, 85, 76, 84, 58, 80, 66, 81, 82, 75, 86, 89, 74, 71, 72, 67, 78, 69, 65, 123, 87, 88, 73, 79, 125, 83, 77, 34, 62, 90, 102, 44, 100, 117, 108, 116, 59, 112, 98, 113, 114, 107, 118, 121, 106, 103, 104, 99, 110, 101, 97, 91, 119, 120, 105, 111, 93, 115, 109, 39, 46, 122};
а вдохновение и теорию я брал из этой статьи
http://i.voenmeh.ru/kafi5/Kam.loc/inform/UTF-8.htm
я делал перекодировку просто таблицей соответсвия
1
byte
Rus1251keys[66] = {70, 60, 68, 85, 76, 84, 58, 80, 66, 81, 82, 75, 86, 89, 74, 71, 72, 67, 78, 69, 65, 123, 87, 88, 73, 79, 125, 83, 77, 34, 62, 90, 102, 44, 100, 117, 108, 116, 59, 112, 98, 113, 114, 107, 118, 121, 106, 103, 104, 99, 110, 101, 97, 91, 119, 120, 105, 111, 93, 115, 109, 39, 46, 122};
а вдохновение и теорию я брал из этой статьи
http://i.voenmeh.ru/kafi5/Kam.loc/inform/UTF-8.htm
Ну тады исходник дайте, на предмет посмотреть ;)
Там банально один цикл
http://arduino.ru/forum/proekty/arduino-bluetooth-klaviatura-s-shifrovan...
я делал перекодировку просто таблицей соответсвия
1
byte
Rus1251keys[66] = {70, 60, 68, 85, 76, 84, 58, 80, 66, 81, 82, 75, 86, 89, 74, 71, 72, 67, 78, 69, 65, 123, 87, 88, 73, 79, 125, 83, 77, 34, 62, 90, 102, 44, 100, 117, 108, 116, 59, 112, 98, 113, 114, 107, 118, 121, 106, 103, 104, 99, 110, 101, 97, 91, 119, 120, 105, 111, 93, 115, 109, 39, 46, 122};
а вдохновение и теорию я брал из этой статьи
http://i.voenmeh.ru/kafi5/Kam.loc/inform/UTF-8.htm
Честно говоря, не вполне ясно, почему в этой таблице почти случайные числа. Если верить данным из статьи по ссылке, код Unicode для любого символа кириллицы получается прибавлением 848 к кодам символов win-1251. Выходит, все сложные алгоритмы и таблицы можно заменить одним арифметическим действием?
Если верить данным из статьи по ссылке, код Unicode для любого символа кириллицы получается прибавлением 848 к кодам символов win-1251. Выходит, все сложные алгоритмы и таблицы можно заменить одним арифметическим действием?
Если внимательно посмотреть соответствие кодировок 1251 и UTF-16:
https://ru.wikipedia.org/wiki/Windows-1251#.D0.9A.D0.BE.D0.B4.D0.B8.D1.8...
то можно заметить, что 64 символе кириллицы (по 32 заглавных и строчных) идут одним непрерывным блоком. Соответственно, все они действительно преобразуются добавлением константы.
Остается буква Ё/ё русского алфавита, а также несколько букв украинского (он же русинский), белорусского, сербского (он же черногорский) и македонского (болгарский целиком помещается в непрерывный 64-символьный блок). Ну и все остальные символы, присутствующие в 1251. Отсюда и "сложные алгоритмы".
Опять же, мы сеейчас говорим про UTF-16, а в Ардуино используется UTF-8 для преобразования которой в UTF-16 тоже нужны некоторые алгоритмы.
Я сейчас конкретно говорю о коде andycat, у него в табличке 66 значений, из чего следует что никаких белорусских или македонских символов там нет. Если все 64 символа русского алфавита за исключением Ё идут единым блоком, то нафига вообще эта таблицва соответсвий?
В русском алфавите 33 буквы, соответственно, 66 символов (различая строчные и прописные). И, повтоторюсь, таблицы далеко не исчерпываются буквами русского алфавита отличными от Ё.
Что касается конкретно кода andycat, то откуда там что берется и что чему соответствует, не разбирался т.к. не интересно. На 1251->utf не похоже. Может КОИ-8, 866, ГОСТ или еще чего. Например, я в своей библиотеке для OLED подобную таблицу делал для преобразования utf-8 в смещение в таблице знакогенератора, которое не аповторяло ни одну из известных таблиц, т.к. знакогенератор не содержал "лишних" с моей точки зрения символов.
Нет, у меня именно идёт преобразование из кода нажатой клавиатуры win1251 в UTF 8 одним действием, и оно работает. У компьютера буду только в понедельник и опишу все "на пальцах"
Вероятно, я бы понял, что Вы хотели сказать, если бы знал, что такое "клавиатура win1251".
С клавиатуры идёт ascii код, соответствующий нажатой кнопке латинской, я в массив забил именно латинские коды а не кириллицу win1251, возможно по этому и происходит недопонимание. Для преобразования из реальных кодов из win1251 достаточно массив поменять по таблице ссылку на которую я выше давал. Буду у компа после обеда - если необходимо - могу построено код прокомментировать.
Вообще-то с клавиатуры идут скан-коды, а в ASCII их преобразует уже драйвер клавиатуры. Который с тем же успехом может преобразовывать их в CP1251, КОИ8, UTF-16 и все, что душенька пожелает. А Вы из ASCII преобразуете в коды кириллицы букв, расположенных на тех же клавишах, что и латинница? Смысл?
А Вы из ASCII преобразуете в коды кириллицы букв, расположенных на тех же клавишах, что и латинница? Смысл?
он раскладку переключает и драйвер клавы даёт ему нужные символы ASCII
Да, мне было лень разбираться и русифицировать библиотеку PS2Keyboard.h и я сам сделал русификацию.