You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
398 lines
8.9 KiB
398 lines
8.9 KiB
|
|
#include <avr/wdt.h> |
|
extern bool menuRedrawPending; |
|
void abastecimento() |
|
{ |
|
StaticJsonDocument<MQTT_MAX_PACKET_SIZE> Json; |
|
|
|
String msgID = generateUID(); |
|
char pub_message[MQTT_MAX_PACKET_SIZE]; |
|
const char* folder = "envios"; |
|
char path[64]; |
|
|
|
quantPulsos = 0; |
|
terminado = false; |
|
|
|
digitalWrite(bomba[tipocombustivel], HIGH); // Liga a bomba |
|
|
|
delayYield(1800); |
|
|
|
abastecendoMillis = millis(); |
|
|
|
if(tipocombustivel != 1) |
|
{ |
|
attachInterrupt(digitalPinToInterrupt(sensor_A[tipocombustivel]), &subindo_A, RISING); |
|
attachInterrupt(digitalPinToInterrupt(sensor_B[tipocombustivel]), &subindo_B, RISING); |
|
} |
|
else |
|
{ |
|
attachPCINT(digitalPinToPCINT(sensor_A[tipocombustivel]), subindo_A, RISING); |
|
attachPCINT(digitalPinToPCINT(sensor_B[tipocombustivel]), subindo_B, RISING); |
|
} |
|
|
|
while (terminado == false) |
|
{ |
|
|
|
// Yield para evitar travamento durante o laço de abastecimento |
|
wdt_reset(); |
|
ESP8266.Process(); |
|
delay(1); |
|
#ifdef ESP8266 |
|
ESP.wdtFeed(); |
|
#else |
|
yield(); |
|
#endif |
|
if(quantPulsos > 0) |
|
{ |
|
volumeAbastecido = quantPulsos / K[tipocombustivel]; |
|
} |
|
else |
|
{ |
|
volumeAbastecido = 0; |
|
} |
|
|
|
if ((millis() - volumeMillis) > 500) |
|
{ |
|
volumeMillis = millis(); |
|
mostraVolume(); |
|
} |
|
|
|
if(volumeAnterior != volumeAbastecido) |
|
{ |
|
volumeAnterior = volumeAbastecido; |
|
abastecendoMillis = millis(); |
|
} |
|
else |
|
{ |
|
processarBotoes(); |
|
} |
|
|
|
if(calibracaoEmAndamento == false) |
|
{ |
|
if ((millis() - abastecendoMillis) > (PAUSA_ABASTECIMENTO * 1000UL)) |
|
{ |
|
digitalWrite(bomba[tipocombustivel], LOW); // Desliga a bomba |
|
mostraVolume(); |
|
terminado = true; |
|
LOGLN(F("Fim da pausa")); |
|
} |
|
} |
|
if((informarVolume == true) && (volumeInformado > 0)) |
|
{ |
|
if(volumeAbastecido >= volumeInformado) |
|
{ |
|
digitalWrite(bomba[tipocombustivel], LOW); // Desliga a bomba |
|
mostraVolume(); |
|
terminado = true; |
|
} |
|
} |
|
} // while |
|
|
|
if(tipocombustivel != 1) |
|
{ |
|
detachInterrupt(digitalPinToInterrupt(sensor_A[tipocombustivel])); |
|
detachInterrupt(digitalPinToInterrupt(sensor_B[tipocombustivel])); |
|
} |
|
else |
|
{ |
|
detachPinChangeInterrupt(digitalPinToPinChangeInterrupt(sensor_A[tipocombustivel])); |
|
detachPinChangeInterrupt(digitalPinToPinChangeInterrupt(sensor_B[tipocombustivel])); |
|
} |
|
|
|
digitalWrite(bomba[tipocombustivel], LOW); |
|
volumeAbastecido = quantPulsos / K[tipocombustivel]; |
|
mostraVolume(); |
|
|
|
if((calibracaoEmAndamento == true) && (volumeAbastecido > 0) && (salvarCalibracao == true)) |
|
{ |
|
for(byte i = 0; i < 3; i++) |
|
{ |
|
fator.K[i] = K[i]; |
|
} |
|
|
|
K[tipocombustivel] = (K[tipocombustivel] * volumeAbastecido) / 20; |
|
|
|
fator.K[tipocombustivel] = K[tipocombustivel]; |
|
|
|
LOG(F("K")); |
|
LOG(tipocombustivel); |
|
LOG(F(" = ")); |
|
LOGLN(K[tipocombustivel]); |
|
|
|
fator.dia[tipocombustivel] = now.Day(); |
|
fator.mes[tipocombustivel] = now.Month(); |
|
fator.ano[tipocombustivel] = now.Year() - 2000; |
|
|
|
for(byte i = 0; i < 3; i++) |
|
{ |
|
LOG(F("Ultima calibracao K")); |
|
LOG(i); |
|
LOG(F(": ")); |
|
|
|
char datestring[26]; |
|
|
|
snprintf_P(datestring, |
|
sizeof(datestring), |
|
PSTR("%02u/%02u/%02u"), |
|
fator.dia[i], |
|
fator.mes[i], |
|
fator.ano[i]); |
|
LOGLN(datestring); |
|
} |
|
gravarFator(); |
|
} |
|
|
|
if(calibracaoEmAndamento == false) { |
|
//Se não tem Odômetro e nem Horímetro não precisa pedir se completou o tanque |
|
if (acesso.odometro == true || (acesso.horimetro == true && acesso.os == false)) { |
|
|
|
indiceMenu = 8; |
|
|
|
clearScreen(170, 90, 630, 154); |
|
|
|
menu9(true); |
|
|
|
while (respondeu == false) |
|
{ |
|
ESP8266.Process(); |
|
wdt_reset(); |
|
delay(10); |
|
#ifdef ESP8266 |
|
ESP.wdtFeed(); |
|
#else |
|
yield(); |
|
#endif |
|
if((millis() - respondeuMillis) > 10000UL) |
|
{ |
|
completou = true; |
|
respondeu = true; |
|
} |
|
else |
|
{ |
|
processarBotoes(); |
|
} |
|
} |
|
} |
|
} |
|
|
|
setFont(MEDIUM, 7, 117, 132, 255, 255, 255); |
|
myGLCD.print((char*)"Enviando dados...", CENTER, 302); |
|
|
|
qntEnvPend++; |
|
|
|
delayYield(2000); |
|
|
|
if(calibracaoEmAndamento == false) |
|
{ |
|
acumulador[tipocombustivel] += volumeAbastecido; |
|
acumuladorSalvo.acumulador[tipocombustivel] = acumulador[tipocombustivel]; |
|
|
|
gravarAcumulador(); |
|
} |
|
|
|
if(calibracaoEmAndamento == true) |
|
{ |
|
valorOdometro = 0; |
|
valorHorimetro = 0; |
|
completou = false; |
|
} |
|
|
|
Json[F("serial")] = String(NUMERO_SERIE); |
|
Json[F("msg")] = msgID; |
|
Json[F("data")] = String(now.Year()) + "-" + String(now.Month()) + "-" + String(now.Day()); |
|
Json[F("hora")] = String(now.Hour()) + ":" + String(now.Minute()) + ":" + String(now.Second()); |
|
|
|
//Busca a hora do final da abastecida |
|
nowFimAbast = rtc.GetDateTime(); |
|
|
|
Json[F("horafim")] = String(nowFimAbast.Hour()) + ":" + String(nowFimAbast.Minute()) + ":" + String(nowFimAbast.Second()); |
|
|
|
copyArray(tagVeiculo, Json["veiculo"]); |
|
copyArray(tagUsuario, Json["abastecedor"]); |
|
Json[F("acumulador")] = acumulador[tipocombustivel]; |
|
Json[F("quantidade")] = volumeAbastecido; |
|
Json[F("hodometro")] = valorOdometro; |
|
if (acesso.os == true) { |
|
if (valorHorimetro > 0) { |
|
Json[F("ordem_servico")] = valorHorimetro; |
|
} |
|
} else { |
|
//NOVO HORIMETRO DIVIDE POR 10 PARA FICAR DECIMAL |
|
float valHorimetroDivisor = 10.0; |
|
Json[F("horimetro")] = valorHorimetro / valHorimetroDivisor; |
|
} |
|
Json[F("operacao")] = operacaoID; |
|
Json[F("talhao")] = talhaoID; |
|
Json[F("safra")] = safraID; |
|
Json[F("rota")] = rotaID; |
|
Json[F("completou")] = completou; |
|
Json[F("tipo")] = tipocombustivel + 1; |
|
Json[F("calibracao")] = calibracaoEmAndamento; |
|
|
|
//PULSOS |
|
Json[F("pulsos")] = quantPulsos; |
|
Json[F("indice")] = K[tipocombustivel]; |
|
|
|
SdFile::dateTimeCallback(dateTime); |
|
|
|
selecionar_SPI(SD_CARD); |
|
delayYield(200); |
|
|
|
byte tentativas = 0; |
|
|
|
while(!SD.begin(SelectSlave_SD, SD_CARD_SPEED) && (tentativas < 5)) |
|
{ |
|
Json[F("msg")] = msgID; |
|
tentativas++; |
|
LOGLN(F("Nao foi possivel acessar o cartao SD")); |
|
ESP8266.Process(); |
|
delay(100); |
|
} |
|
|
|
LOG(F("Tentativas: ")); |
|
LOGLN(tentativas); |
|
|
|
if(tentativas >= 5) |
|
{ |
|
LOGLN(F("Nao foi possivel acessar o cartao SD")); |
|
} |
|
else |
|
{ |
|
if(!SD.exists(folder)) |
|
{ |
|
if (!SD.mkdir(folder)) |
|
{ |
|
LOG(F("Nao foi possivel criar a pasta ")); |
|
LOGLN(folder); |
|
} |
|
else |
|
{ |
|
LOG(F("A pasta ")); |
|
LOG(folder); |
|
LOGLN(F(" foi criada")); |
|
} |
|
} |
|
else |
|
{ |
|
LOG(F("A pasta ")); |
|
LOG(folder); |
|
LOGLN(F(" existe")); |
|
} |
|
|
|
snprintf(path, sizeof(path), "%s/%s.txt", folder, msgID.c_str()); |
|
while(SD.exists(path)) |
|
{ |
|
LOG(F("O arquivo ")); |
|
LOG(path); |
|
LOGLN(F(" existe")); |
|
msgID = generateUID(); |
|
snprintf(path, sizeof(path), "%s/%s.txt", folder, msgID.c_str()); |
|
} |
|
|
|
file = SD.open(path, FILE_WRITE); |
|
|
|
if (!file) |
|
{ |
|
LOG(F("Nao foi possivel criar ")); |
|
LOGLN(path); |
|
} |
|
else |
|
{ |
|
if (serializeJson(Json, file) == 0) |
|
{ |
|
LOG(F("Falha ao gravar dados em ")); |
|
LOGLN(path); |
|
} |
|
else |
|
{ |
|
LOG(F("envios/")); |
|
LOG(msgID); |
|
LOG(F(".txt")); |
|
LOGLN(F(" gravado com sucesso.")); |
|
} |
|
} |
|
file.close(); |
|
} |
|
|
|
LOGLN(F("Enviando dados de abastecimento...")); |
|
|
|
if (MQTT_connected == true) |
|
{ |
|
serializeJson(Json, pub_message); |
|
MQTT.publish(TOPICO_PUB_ENVIO_ABASTECIMENTO, pub_message, false); |
|
|
|
LOGLN(F("Mensagem enviada:")); |
|
|
|
#ifdef DEBUG |
|
serializeJsonPretty(Json, Serial); |
|
#endif |
|
|
|
LOGLN(F("")); |
|
} |
|
else |
|
{ |
|
LOGLN(F("MQTT desconectado!")); |
|
} |
|
|
|
salvarCalibracao = false; |
|
calibracaoEmAndamento = false; |
|
calibrando = false; |
|
volumeAbastecido = 0; |
|
informarVolume = false; |
|
volumeInformado = 0; |
|
indiceMenu = 0; |
|
iniciar = false; |
|
|
|
clearScreen(10, 90, 799, 479); |
|
menuRedrawPending = true; |
|
} |
|
|
|
void subindo_A() |
|
{ |
|
if(tipocombustivel != 1) |
|
{ |
|
attachInterrupt(digitalPinToInterrupt(sensor_A[tipocombustivel]), &descendo_A, FALLING); |
|
} |
|
else |
|
{ |
|
attachPCINT(digitalPinToPCINT(sensor_A[tipocombustivel]), descendo_A, FALLING); |
|
} |
|
} |
|
|
|
void subindo_B() |
|
{ |
|
if(tipocombustivel != 1) |
|
{ |
|
attachInterrupt(digitalPinToInterrupt(sensor_B[tipocombustivel]), &descendo_B, FALLING); |
|
} |
|
else |
|
{ |
|
attachPCINT(digitalPinToPCINT(sensor_B[tipocombustivel]), descendo_B, FALLING); |
|
} |
|
} |
|
|
|
void descendo_A() |
|
{ |
|
if(tipocombustivel != 1) |
|
{ |
|
attachInterrupt(digitalPinToInterrupt(sensor_A[tipocombustivel]), &subindo_A, RISING); |
|
} |
|
else |
|
{ |
|
attachPCINT(digitalPinToPCINT(sensor_A[tipocombustivel]), subindo_A, RISING); |
|
} |
|
quantPulsos++; |
|
} |
|
|
|
void descendo_B() |
|
{ |
|
if(tipocombustivel != 1) |
|
{ |
|
attachInterrupt(digitalPinToInterrupt(sensor_B[tipocombustivel]), &subindo_B, RISING); |
|
} |
|
else |
|
{ |
|
attachPCINT(digitalPinToPCINT(sensor_B[tipocombustivel]), subindo_B, RISING); |
|
} |
|
quantPulsos++; |
|
}
|
|
|