SD кажется слишком медленным для SMTP
Я тоже задавал этот вопрос на форуме arduino.
Я использовал SMTP до использования client.print (и client.println), но теперь я пытаюсь переместить как можно больше текста из оперативной памяти на SD (и поэтому мне нужна библиотека <SD.h>). Это не работает, и я думаю, что это может быть потому, что SMTP-сервер "умирает от скуки", ожидая, когда мой Arduino прочитает с SD-карты и запишет ее клиенту (серверу?). В приведенном ниже коде я включил то, что я пытаюсь (оно будет раскомментировано, если вы скопируете+вставите код), и то, что уже работает (что будет прокомментировано, когда вы скопируете+вставите код, но вы можете раскомментировать и прокомментировать другой раздел относительно легко). Текстовый файл у меня есть на SD-карте в коде (с комментариями). Если кто-нибудь может придумать обходной путь, это было бы здорово.
#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>
//-v--- Ethernet -----------
byte MyMac[] = {0xFE, 0xED, 0xBE, 0xEF, 0xFE, 0xED}; // <- The physical address of the machine's network card. Should be unique (no two network cards have the same MAC address)
byte MyIp[] = {1, 1, 1, 1}; // <- This is the not the real IP address, but for the real address I have verified that the static IP works for sending mail
byte Dns[] = {1, 1, 1, 1}; // <- Not the real DNS but I got it once through Serial.println(Ethernet.dnsServerIP()); and I know that it works
byte Gateway[] = {1, 1, 1, 1}; //<- Not real
byte Subnet[] = {1, 1, 1, 1}; //<- Not Real
EthernetClient client ;
//-^--- Ethernet -----------
//-v-- Smtp --------
char ServerChar[] = "blahblah";
//-^-- Smtp --------
//-v--- SD ------
File theFile; String line;
//-^--- SD ------
void setup() {
Ethernet.begin(MyMac, MyIp, Dns, Gateway, Subnet);
SD.begin(4);
bool test = TrySend();
}
void loop() {
// put your main code here, to run repeatedly:
}
bool TrySend(){
//*-v---- What I am trying ---
bool SuccessOrNot;
if(client.connect(ServerChar, 25)){
SuccessOrNot = true;
theFile = SD.open("Smtp.txt"); //Smtp.txt is listed toward the bottom of the code
if(theFile){
while(theFile.available()){
client.write( theFile.read() );
}
theFile.close();
}
}
else{ SuccessOrNot = false; }
return SuccessOrNot;
//-^---- What I am trying --- */
/*-v-- The following works if used in place of [What I am trying] ---
bool SuccessOrNot;
if(client.connect(ServerChar, 25)){
SuccessOrNot = true;
client.println("EHLO ktlan");
client.println("AUTH LOGIN");
//-v- Most SMTP servers require verification in the form of base64-encoded username and base64-encoded password. However, since your IP must be whitelisted by the SMTP server, you don't need authentication
//client.println("ThisIsInBase64"); // Encoded version of '[email protected]'
//client.println("ThisIsInBase64"); // Encoded version of the password
//-^-
client.println("MAIL FROM:<[email protected]>");
client.println("RCPT TO:<[email protected]>");
client.println("DATA");
client.println("to:[email protected]");
client.println("from:[email protected]");
client.print("SUBJECT: TRIGGER");
client.println();
client.println("The temperature Monitor Triggered.");
client.println(".");
client.println("QUIT");
}
else{ SuccessOrNot = false; }
//-^-- The following works if used in place of [What I am trying] ---*/
}
/*-v--- Smtp.txt -------
EHLO ktlan
AUTH LOGIN
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
to:[email protected]
from:[email protected]
SUBJECT: TRIGGER
The temperature Monitor Triggered.
.
QUIT
//-^--- Smtp.txt -------*/
// NO NEED for authentication. For many Smtp servers you need:
//client.println("ThisIsInBase64"); // Encoded version of '[email protected]'
//client.println("ThisIsInBase64"); // Encoded version of the password
// My IP must be whitelisted by the SMTP server, and since it is, I don't need authentication
@elscan, 👍1
Обсуждение1 ответ
Попробуйте более простой подход (с некоторым рефакторингом кода)
bool TrySend(){
if(client.connect(ServerChar, 25)){
theFile = SD.open("Smtp.txt");
if(theFile){
while(theFile.available()){
client.print(theFile.readStringUntil('\n'));
client.print('\n');
}
theFile.close();
return true;
}
}
return false;
}
В качестве примечания вы можете рассмотреть некоторую лучшую структуру кода (например, локальные переменные). Но я предполагаю, что это всего лишь образец/тест. Кроме того, приведенный выше код предполагает, что файл использует
\r\n
в конце каждой строки. Если у него есть только\n
, то вы можете просто использовать:client.println(файл.readStringUntil('\n'));
(обратите внимание напечать*ln*
).println
отправляет оба\r\n
.
- Клиент MQTT на Arduino + SIM900
- связь между двумя arduino с помощью ENC28J60?
- Пример UDPSendReceiveString с использованием Arduino Due с Ethernet-модулем ENC28J60
- ARDUINO MODBUS TCP СОЕДИНЕНИЕ
- Arduino Yun получает UDP-пакеты, но печатает их с помощью тарабарщины
- Как получить HTTPS на Arduino?
- Основная связь Arduino ModBus RTU с проблемой измерителя мощности
- Последовательная связь между ESP8266 и Arduino Uno
Было бы очень полезно также увидеть SMTP-серверную сторону вещей (журналов), если у вас есть к ней доступ. Кроме того, вы не ждете никаких ответов от сервера, поэтому нет способа определить, когда сервер готов к вашей следующей команде., @StarCat
Вы читаете и пишете байт за раз, что может быть не оптимальным. Попробуйте сделать это большими кусками (размер страницы SD, если у вас достаточно памяти), @Mat
Многие почтовые серверы откажутся обслуживать клиента, который отправляет EHLO, прежде чем он отправит свой идентификационный баннер., @Majenko
Спасибо всем. Добавил "ReadClient()", он работает []. Пробовал readStringUntil(), печатать построчно, работает [], пробовал не возвращать bool, работает (!?) ... вернитесь обратно к исходному коду, работает []. Я говорю [], потому что при повторной загрузке кода электронная почта отправляет, но не отправляет другую при сбросе кнопки и не отправляет, если повторно загружается с активным последовательным монитором. Был 1 раз в устранении неполадок, он работал полностью, и я видел вывод клиента на последовательный монитор и электронную почту при каждом сбросе. Не мог воспроизвести. Извините за неясность: поскольку я утверждаю, что результаты неповторимы, я должен опубликовать [длинные] инструкции. Я переустанавливаю &, если вы это сделаете., @elscan