Ir ao conteúdo
  • Cadastre-se

DeadlyNicotine

Membro Pleno
  • Posts

    39
  • Cadastrado em

  • Última visita

  1. Boas tardes a todos, peço desculpa pelo sumiço, mas tenho tido dias muito difíceis e como tal não tenho tido vontade para nada. Tenho muita coisa por responder e antes de mais queria agradecer a todos pela ajuda, até por terem dedicado boa parte do vosso tempo (o bem mais precioso que temos na vida) a ajudar-me neste projeto que tinha tudo para falhar, não tenho palavras para agradecer. @Sérgio Lembo, achas que é um circuito muito difícil de montar, mais difícil do que aquele do vídeo, sabendo de antemão que eu não sei ler diagramas , será que consigo tensões e correntes ainda mais baixas, tipo para metade em cada? @.if, Não percebi o porque de uma "tensão maior deixar o circuito mais confortável", porque 12V e não começar com o carregador que tinha planeado? Sobre a PCB, não conhecia essa eletromigração, parece muito dendrites de manganês que às vezes se vê em rochas, eu não penso fazer uma PCB de raiz, mas sim usar uma breadboard. @MOR_AL, o teu circuito parece o mais simples, mas assim teria uma tensão de 470 mV, o do vídeo tem uma tensão na ordem de 15 mV e diz que é um dos segredos para cristalizar cristais lentamente e euédricos (bem definidos), não podia com este sistema meter a tensão a 5 mV? No final disto tudo, gostaria de pagar um café a todos vocês, mas quando isto começar a andar, envio uma mensagem privada a cada, espero não ir contra as regras do forum.
  2. Antes de mais, obrigado aos três pelas respostas, irei ler com calma assim que tiver mais tempo, estou ainda a tentar arranjar um motorzinho de um hdd velho. Como o amigo @.if postula, a "falta de conhecimento" dele na química é bem menor do que a minha na eletrónica, portanto, preciso de tempo. Não tenho palavras para agradecer o esforço que cada um que comentou aqui fez para ajudar este projeto, perderam parte do vosso bem mais precioso na vida que é o tempo, ora para comentar, ora para até fazer circuitos. Pagaria a todos um bom copo de vinho do Porto se viessem aqui, talvez possa enviar uns reais para um cafezinho, depois de ter o projeto a correr e de ter as minhas finanças um pouco mais positivas . Também tem sido difícil arranjar vontade para avançar com isto e nem sabem o quão eu gostaria de ter/ver o circuito a correr, mas tudo há-de lá chegar, afinal, é o sonho que move o poeta.
  3. Boas tardes @.if, eu ainda não comecei, ainda está na fase de planeamento. Em relação ao projeto desse vídeo e onde fui buscar a ideia (o canal já cristalizou cobre e estanho, eu planeio cristalizar todos os metais sendo o meu principal objetivo ou sonho, o uranio ainda que falte muito para lá chegar), esta experiência é em tudo igual ao do vídeo sendo as diferenças, o sal que uso, ainda que sejam ambos cloretos de estanho, o dela encontra-se de uma forma desidratada e o meu encontra-se numa forma azeotrópica, isto é, tem existe uma relação com o HCl que me impede de obter o composto sobre a forma de um sólido. Outra diferença importante e a corrente/tensão de entrada, ele usa um transformador de 7.5 V e uma tensão de 200 mA e eu estava a pensar usar um transformador que entrega 6 V e 150 mA, finalmente mas não menos importante, a tensão/corrente que ele obtém usando esse circuito, 0.25V e cerca de 15 mA, com estes valores o metal cresce muito lentamente (durante vários meses e essa é a razão pela qual eu gostaria de começar e ir estudando e percebendo o circuito à medida que vou vendo o estanho a cristalizar) no meu caso, eu gostaria de atingir valores ainda mais baixos, tipo 0.05-0.1V e 5 ou menos mA (não pode ultrapassar os 10 mA), não sei são suficientes para começar a cristalização e sei que estes valores são os iniciais pois à medida que os cristais se formam, a resistência do sistema baixa e a corrente aumenta, por isso eu gostaria de ter algum sistema de resistência variável para ir controlando a corrente. Portanto, eu estou a pensar nos próximos tempos, replicar o circuito que ele tem, mas adicionar mais díodos 1N4007, alguém poderia dizer o valor daquele capacitor/condensador de cerâmica que usa? Poderei usar um LM317T invés do LM317, é 10x mais barato na loja de eletrónica que conheço, qual potenciómetro regulável é aquele azul? Na loja onde compro existem vários modelos, desde de multivolta linear verticais a logarítmicos mono metálicos, qual aconselham e qual o valor? Finalmente, ele criou um circuito parecido usando também um LM317 para correr o motor a muito baixo RPM, posso aqui também usar o LM317T, independentemente do motor (devo ir buscar a um leitor de CDs, quando o tiver, digo as especificações). É isto, tendo tudo iniciado, acho que poderei ir aprendendo como funciona o circuito (principalmente a física por detrás que é o que mais gosto) e ver, dia após dia, na secretária da faculdade onde passo os meus dias, os cristais a formarem-se. Outra questão que me lembrei agora, o meu multímetro só consegue ler até 200 mV, portanto, não vou conseguir saber qual tensão fixa do sistema, mas medindo a corrente (o limite inferior é 200 uA) e a resistência (limite inferior é 200 Ohm), posso calcular a tensão pela lei de Ohm certo? Obrigado por tudo, cumprimentos!
  4. Boas tardes a todos (horário de Lisboa), antes de mais gostaria de desejar um bom natal a todos, espero que tenham passado a consoada com quem traz mais cor ao vosso mundo! @Sérgio Lembo, confesso ter-me perdido um pouco nas entrelinhas, nas "tecnicidades", eu sei que na pratica, controlar a corrente é algo difícil ou até impossível no ambiente em que estou a tentar montar, mas o que gostaria é constranger a tensão a 0.1V e como a corrente é fator dessa mesma tensão e da resistência total do sistema, sei que será impossível controlar todos os fatores dos quais depende a resistência, contudo, há muitas variáveis que desconheço. Decidi começar por estanho e a solução que tenho desse metal foi obtida pela reação de solda à base de estanho com HCl não obedecendo a nenhuma estequiometria e, portanto, não sei sequer a concentração da minha solução eletrolítica, mas se usar um ânodo/cátodo pequenos, uma grande distância entre ambos posso, idealmente, constranger a corrente a um valor muito baixo, posso ainda ir mudando estas variáveis de forma a tentar constranger a corrente, agora estava aqui a pensar, será que posso meter um arduino que me esteja sempre a medir a corrente e tensão, acham que ele consegue medir valores muito pequenos? Será que o circuito é simples e barato (já tenho o arduino) para que uma pessoa como eu, com um conhecimento muito primitivo, possa montar? @aphawk, podes elaborar mais a tua experiência? Eu acho que não posso mexer na concentração, nesse vídeo, quando o autor diminui a concentração, o estanho cristaliza muito rapidamente gerando cristais finos e longos (em geologia diríamos que a taxa de nucleação é baixa, poucos cristais e a taxa de difusão ou crescimento é alta), a tua ideia de fixar a tensão, dentro do meu entendimento, era o mais fácil e o mais lógico, também calculo que à medida que os cristais vão crescendo a corrente irá aumentar pois acredito que a resistência total do sistema aumente, mas tenho uma questão, não poderia usar uma resistência regulável para tentar combater o aumento da corrente por cristalização? Não percebi a parte da tensão aumentar com a cristalização sabendo que fixamos a tensão a um limite (0.1V). Finalmente, mas não menos importante, @.if o sobrevivente! Em relação às questões metafísicas, acho que o segredo da vida (ainda que seja um crónico niilista perante a existência) consiste em aproveitar os pequenos momentos da vida, mas tem sido difícil, há dias muito difíceis, há dias que acho que estou perto colocar um ponto final a isto tudo com um alcaloide que extrai de uma planta, mas como dizem os demais, enquanto há vida, há esperança. Eu estive a ver um pouco o link que envias-te e confesso não ter visto com atenção, pelo menos à parte da eletrónica, a parte física é simples, mas a eletrónica... Tenho ainda muito a aprender, mas eu gostaria de ir aprendendo, dado que o projecto vai demorar, idealmente, meses a cristalizar (e considerando que gostaria de o fazer para uma quantidade grande de metais) teria tempo para ir percebendo os in and out's do sistema, acredito que a eletrónica seja algo simples que eu possa perceber com mais tempo e espero com mais vontade. Em relação ao motor que sugeriste, o valor mais barato que encontro aqui por Lisboa é cerca de 54 reais e neste momento estou com pouco dinheiro, portanto, terei de arranjar outra solução. Será que eu não poderia montar um circuito como o do vídeo, mas fixando a tensão a 0.1V e ir estudando a partir dai? Obrigado a todos!
  5. Sabe de mais alguma informação que possa ajudar?
  6. Portanto, em primeira pessoa? lembra-se de alguma arma, inimigo, ou localização específica? Como o @xlemes perguntou, sabendo a fonte, pode-se tornar fácil achar! Acho que o youtube pode ser uma boa fonte para começar a procurar, achei estes vídeos, será algum destes jogos?
  7. Boas tardes @MOR_AL e @albert_emule e restantes, antes de mais, gostaria de pedir desculpa a ambos pelo meu silêncio, não posso agradecer o tempo, o vosso bem mais precioso nesta curta vida, que dedicaram a ajudar-me! Eu tenho tido alguns problemas graves (ou nem tanto) de saúde mental e por isso eu perdi o interesse em basicamente tudo. Encontro-me neste momento a tentar virar a página e gostaria de retomar um conjunto de projetos que ficaram na gaveta, com esse fim, gostaria de perguntar se me podia ajudar, mais uma vez. Eu tenho de rever tudo o que foi escrito, mas pelo que percebi, eu posso limitar a tensão no valor que eu quiser e a corrente vai ser produto da resistência total do sistema (pela lei de Ohm) e, portanto, controlando a concentração da solução eletrolítica, a distância entre cátodo/ânodo, a temperatura, a própria tensão entre outros parâmetros eu controlo a corrente. Então, será que eu vou conseguir a medir com um multímetro normal ou calculo-a através da lei de Ohm visto que talvez consiga medir a resistência? Como vos disse, sou geólogo e não percebo muito de eletrónica e por isso peço que tenham alguma paciência, eu vou dar o meu melhor (dentro dos meus possíveis) para estudar o circuito, dado que vai demorar muito tempo a cristalizar, eu vou ver se para a semana consigo estudar o mínimo para começar com o sistema a correr. Outra coisa, eu acho que seria imperativo colocar também um motorzinho a correr a muito baixo RPM's (como no vídeo), poderei ter um circuito como no vídeo para controlar a velocidade? Poderá ser qualquer motorzinho? Será muito difícil de montar? Já tenho a solução quase pronta, decidi começar por cristalizar estanho pelo facto de não oxidar e da solução ser muito clara e puder ver o progresso dia após dia. Acham que me podem ajudar, uma última vez (espero)? Obrigado a todos, cumprimentos!
  8. Boas noites a todos. Eu tenho um código que é feito para funcionar com um ESP8266 usando um ecrã TFT da Adafruit, porém eu gostaria de o converter para trabalhar num Arduino MEGA, porém estou a ter algumas dificuldades. O código é o seguinte: include <Arduino.h> #include <MCUFRIEND_kbv.h> #include <EEPROM.h> #include "SPI.h" #include "Adafruit_GFX.h" #include <Fonts/FreeSans9pt7b.h> #include <Fonts/FreeSans12pt7b.h> #include "Adafruit_ILI9341.h" #include <TouchScreen.h> #define CS_PIN D2 XPT2046_Touchscreen ts(CS_PIN); #define TS_MINX 250 #define TS_MINY 200 // calibration points for touchscreen #define TS_MAXX 3800 #define TS_MAXY 3750 #define TFT_DC D4 #define TFT_CS D8 #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define DOSEBACKGROUND 0x0455 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); Pelo que tenho andado a pesquisar, tenho de usar os seguintes comandos (incluindo o pontos de calibração do código anterior): MCUFRIEND_kbv tft(ILI9488, A3, A2, A1, A0, A4); #define CS=A3 #define RS=A2 #define WR=A1 #define RD=A0 #define RST=A4 TouchScreen ts = ts(pinXP, pinYP, pinXM, pinYM, 300) //300 como resistência Porém não sei o que mais devo substituir, pois não consigo perceber como substituir a última linha do 1º código, alguém me poderia ajudar? Observação: não coloquei o código todo, pois são mais de 1500 linhas e já tentei esclarecer algumas dúvidas, inclusive neste fórum, mas se quiserem que coloque tudo é só pedirem. Peço também que não sejam muito técnicos pois é o meu primeiro projeto com um Arduino. Obrigado e cumprimentos a todos!
  9. Bons dias Thiago, ótima questão! Pelo que tive a ler, terá que instalar os packages primeiro usando o pip (através do prompt no diretório do projecto) e só depois fazer o executável (segundo o usuário livinlivin10 que se encontra nos comentários do próprio vídeo). Eu nunca fiz, como referi anteriormente, nenhum executável com o Python (ou Píton para os amigos) e portanto não sou a pessoa mais indicada para o ajudar. Se quiser posso perguntar a algum professor da faculdade onde estudo. Cumprimentos.
  10. Boas noites, Essa é uma ótima pergunta. eu uso python na faculdade, aplicado à resolução de métodos numéricos, mas confesso que nunca tinha colocado a opção de compilar o meu código (até porque nunca me foi necessário). Ao pesquisar no youtube achei este vídeo que explica bem como o fazer, porém esta em inglês (se precisar de ajuda com esse vídeo, eu posso traduzir os passos para você). O link do vídeo referido é o seguinte: Cumprimentos.
  11. Antes de mais, gostaria de agradecer a ambos pelo interesse demonstrado neste projeto :), também gostaria de pedir desculpas pela demora a responder, mas tenho andado com muito trabalho na faculdade e portanto não tenho tido muito tempo para o lazer. @albert_emule, ainda tenho de digerir o que disse , mas faz todo o sentido (até onde consegui perceber), ou seja, neste caso, à medida que o cristal vai crescer em direção ao outro terminal (como o @MOR disse) a corrente que consome vai se alterando mesmo metendo a tensão fixa, portanto eu nunca posso fixar os dois. A parte do divisor resistivo é que ainda não percebi, mas amanhã tenho muito tempo para pensar nisso com calma, mas a sua ideia é muito inteligente e quero-a explorar melhor. @MOR, Por que considera que é importante manter a corrente nos 13 Ma? Eu não posso mexer muito no eletrólito, pois de aumento muito a concentração, os cristais crescem muito rápido, com alta taxa de nucleação (i.e. muitos cristais) e muito anédricos (i.e. "imperfeitos"), ao mesmo tempo não pode ser muito baixa pois acontece algo similar até ao que pude inferir, portanto esse parâmetro é "fixo" (pois ao usar iões para formar os cristais estou a devolver esses iões à solução pela redução no outro terminal num rácio de 1:1). Confesso que ainda tenho de ler um pouco mais sobre esse tópico, mas assim que perceber como funciona o circuito do @albert_emule, vou o meter em prática e vou-vos mantendo informados sobre o estado de cristalização :). Obrigado outra vez e em especial aos dois, mas também a todos que têm acompanhado este projeto . Cumprimentos.
  12. Boas noites a todos (Portugal), eu tenho estado bastante ocupado com a academia e não tenho tido muito tempo para "brincar" com este projeto, mas gostaria de o avançar/finalizar. Eu já consegui, com ajuda, comentar tudo o que era referente ao wi-fi (que não me interessa), porém eu acho que ainda existe um pedaço de código referente ao wi-fi que não consigo tirar pois o suposto pedaço compõe um ciclo maior onde é inserido parte do código essencial (considerando o wi-fi não essencial), será que poderia o remover? Ou vou ter de o deixar (colocarei o código em baixo)? Segundo, Acho o que já consegui perceber, para obter os pulsos do geiger (i.e. partículas radioativas) terei de colocar o meu pin INT no pino nº5 do meu Arduino e para obter informações da tensão da bateria tenho de de ligar a bateria no polo nº0 do Arduino, certo? Porém, o projeto é feito para um ESP8266 e não para um arduino, sendo necessário "converter" os pinos do ESP para os do Arduino, como está em comentário logo no inicio do código, alem disso, devido ao ecrã de 3,5'', eu só tenho um número de pinos, será que posso usar pinos digitais para ambos? Por fim, explicaram-me que o Arduino é um processador de 8 bits enquanto o ESP é de 16 e por isso terei que trocar algumas das variáveis de long/unsigned long to int/unsigned int, mas não percebi bem o porque e é um assunto que gostaria de perceber melhor, alguém tem alguma bibliografia que pudesse indicar de forma a perceber o impacto que as funções têm no código? Apenas descobri um link que comparava a velocidade, no caso, no calculo de números primos usando variáveis de 16 bit vs 8 bits e achei muito interessante, porém complicado Código: #include <Arduino.h> //#include <ESP8266WiFi.h> //#include <EthernetClient.h> //#include <DNSServer.h> //#include <ESP8266WebServer.h> //#include <WifiManager.h> #include <EEPROM.h> #include "SPI.h" #include "Adafruit_GFX.h" #include <Fonts/FreeSans9pt7b.h> #include <Fonts/FreeSans12pt7b.h> #include "Adafruit_ILI9341.h" #include <XPT2046_Touchscreen.h> // Map ESP8266 pin names to rduino pins const byte D0 = 2; const byte D1 = 3; const byte D2 = 4; const byte D3 = 5; const byte D4 = 6; const byte D5 = 7; const byte D6 = 8; const byte D7 = 9; const byte D8 = 10; // WiFi variables //unsigned long currentUploadTime; //unsigned long previousUploadTime; //int passwordLength; //int SSIDLength; //int channelIDLength; //int writeAPILength; //char ssid[20]; //char password[20]; //char channelID[20]; // = "864288"; //char channelAPIkey[20]; // = "37SAHQPEQ7FOBC20"; //char server[] = "api.thingspeak.com"; //int attempts; // number of connection attempts when device starts up in monitoring mode //WiFiClient client; #define CS_PIN D2 XPT2046_Touchscreen ts(CS_PIN); #define TS_MINX 250 #define TS_MINY 200 // calibration points for touchscreen #define TS_MAXX 3800 #define TS_MAXY 3750 #define TFT_DC D4 #define TFT_CS D8 #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define DOSEBACKGROUND 0x0455 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); const int interruptPin = 5; long count[61]; long fastCount[6]; // arrays to store running counts long slowCount[181]; int i = 0; // array elements int j = 0; int k = 0; int page = 0; long currentMillis; long previousMillis; unsigned long currentMicros; unsigned long previousMicros; unsigned long averageCount; unsigned long currentCount; // incremented by interrupt unsigned long previousCount; // to activate buzzer and LED unsigned long cumulativeCount; float doseRate; float totalDose; char dose[5]; int doseLevel; // determines home screen warning signs int previousDoseLevel; bool ledSwitch = 1; bool buzzerSwitch = 1; bool wasTouched; int integrationMode = 0; // 0 = medium, 1 = fast, 2 == slow; bool doseUnits = 0; // 0 = Sievert, 1 = Rem unsigned int alarmThreshold = 5; unsigned int conversionFactor = 175; int x, y; // touch points // Battery indicator variables int batteryInput; int batteryPercent; int batteryMapped = 212; // pixel location of battery icon int batteryUpdateCounter = 29; // EEPROM variables const int saveUnits = 0; const int saveAlertThreshold = 1; // Addresses for storing settings data in the EEPROM const int saveCalibration = 2; const int saveDeviceMode = 3; const int saveLoggingMode = 4; const int saveSSIDLen = 5; const int savePWLen = 6; const int saveIDLen = 7; const int saveAPILen = 8; // Data Logging variables int addr = 200; // starting address for data logging char jsonBuffer[14000] = "["; char data[14500] = "{\"write_api_key\":\""; unsigned long currentLogTime; unsigned long previousLogTime; // Timed Count Variables: int interval = 5; unsigned long intervalMillis; unsigned long startMillis; unsigned long elapsedTime; int progress; float cpm; bool completed = 0; int intervalSize; // stores how many digits are in the interval // Logging variables bool isLogging; bool deviceMode; // interrupt routine declaration // void ICACHE_RAM_ATTR isr(); // ESP8266-style void isr(); unsigned int previousIntMicros; // timers to limit count increment rate in the ISR const unsigned char gammaBitmap [] PROGMEM = { 0x30, 0x00, 0x78, 0x70, 0xe8, 0xe0, 0xc4, 0xe0, 0x84, 0xc0, 0x05, 0xc0, 0x05, 0x80, 0x07, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x3e, 0x00, 0x1c, 0x00, 0x00, 0x00 }; const unsigned char betaBitmap [] PROGMEM = { 0x00, 0xc0, 0x00, 0x03, 0xf0, 0x00, 0x07, 0x18, 0x00, 0x06, 0x18, 0x00, 0x0e, 0x18, 0x00, 0x0e, 0x18, 0x00, 0x0e, 0xf8, 0x00, 0x0e, 0x1c, 0x00, 0x0e, 0x0c, 0x00, 0x0e, 0x0c, 0x00, 0x0e, 0x0c, 0x00, 0x0e, 0x0c, 0x00, 0x0f, 0x1c, 0x00, 0x0f, 0xf8, 0x00, 0x0e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char wifiBitmap [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x0f, 0xfe, 0x00, 0x3f, 0xff, 0x80, 0x78, 0x03, 0xc0, 0xe0, 0x00, 0xe0, 0x47, 0xfc, 0x40, 0x0f, 0xfe, 0x00, 0x1c, 0x07, 0x00, 0x08, 0x02, 0x00, 0x01, 0xf0, 0x00, 0x03, 0xf8, 0x00, 0x01, 0x10, 0x00, 0x00, 0x40, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char settingsBitmap[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x7f, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x7f, 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xf9, 0xff, 0xf9, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x1f, 0xff, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x01, 0xff, 0xff, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xe0, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xf9, 0xff, 0xf9, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x7f, 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x7f, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char buzzerOnBitmap[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x07, 0x00, 0x00, 0x00, 0x3f, 0x80, 0xc7, 0x80, 0x00, 0x00, 0xff, 0x80, 0xe3, 0x80, 0x00, 0x01, 0xff, 0x80, 0xf3, 0xc0, 0x00, 0x03, 0xff, 0x80, 0x71, 0xc0, 0x00, 0x07, 0xff, 0x8c, 0x79, 0xc0, 0x3f, 0xff, 0xff, 0x9e, 0x38, 0xe0, 0x3f, 0xff, 0xff, 0x8e, 0x38, 0xe0, 0x3f, 0xff, 0xff, 0x8e, 0x3c, 0xe0, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0xe0, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x60, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0xe0, 0x3f, 0xff, 0xff, 0x8e, 0x3c, 0xe0, 0x3f, 0xff, 0xff, 0x8e, 0x38, 0xe0, 0x3f, 0xff, 0xff, 0x9e, 0x38, 0xe0, 0x00, 0x07, 0xff, 0x8c, 0x79, 0xc0, 0x00, 0x03, 0xff, 0x80, 0x71, 0xc0, 0x00, 0x00, 0xff, 0x80, 0xf1, 0xc0, 0x00, 0x00, 0x7f, 0x80, 0xe3, 0x80, 0x00, 0x00, 0x3f, 0x80, 0xc7, 0x80, 0x00, 0x00, 0x1f, 0x80, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0e, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char buzzerOffBitmap[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x8f, 0x00, 0x78, 0x7f, 0xff, 0xff, 0x8f, 0x80, 0xf8, 0x7f, 0xff, 0xff, 0x8f, 0xc1, 0xf8, 0x7f, 0xff, 0xff, 0x87, 0xe3, 0xf0, 0x7f, 0xff, 0xff, 0x83, 0xf7, 0xe0, 0x7f, 0xff, 0xff, 0x81, 0xff, 0xc0, 0x7f, 0xff, 0xff, 0x80, 0xff, 0x80, 0x7f, 0xff, 0xff, 0x80, 0x7f, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x7f, 0x00, 0x7f, 0xff, 0xff, 0x80, 0xff, 0x80, 0x7f, 0xff, 0xff, 0x81, 0xff, 0xc0, 0x7f, 0xff, 0xff, 0x83, 0xf7, 0xe0, 0x7f, 0xff, 0xff, 0x87, 0xe3, 0xf0, 0x7f, 0xff, 0xff, 0x8f, 0xc1, 0xf0, 0x7f, 0xff, 0xff, 0x8f, 0x80, 0xf8, 0x3f, 0xff, 0xff, 0x8f, 0x00, 0x70, 0x3f, 0xff, 0xff, 0x84, 0x00, 0x20, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char ledOnBitmap[] PROGMEM = { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0x00, 0xc0, 0x00, 0x00, 0x1c, 0x07, 0x01, 0xc0, 0x00, 0x00, 0x1e, 0x07, 0x03, 0xc0, 0x00, 0x00, 0x0e, 0x07, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1f, 0xc0, 0x03, 0xc0, 0x0f, 0x80, 0x7f, 0xf0, 0x0f, 0x80, 0x07, 0xc1, 0xff, 0xfc, 0x1f, 0x00, 0x03, 0xc3, 0xe0, 0x3e, 0x1e, 0x00, 0x00, 0x07, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x00, 0x7f, 0x1c, 0x00, 0x01, 0xc3, 0xf0, 0x7f, 0x1c, 0x00, 0x01, 0xc7, 0xf0, 0x3c, 0x0e, 0x00, 0x03, 0x81, 0xe0, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0f, 0x00, 0x00, 0x01, 0xc3, 0xc0, 0x1e, 0x1c, 0x00, 0x07, 0xc1, 0xc0, 0x1c, 0x1f, 0x00, 0x0f, 0x81, 0xe0, 0x3c, 0x0f, 0x80, 0x1e, 0x00, 0xe0, 0x38, 0x03, 0xc0, 0x0c, 0x00, 0xe0, 0x38, 0x01, 0x80, 0x00, 0x00, 0xf0, 0x78, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00}; const unsigned char ledOffBitmap[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x78, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00}; const unsigned char backBitmap [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void drawHomePage(); // page 0 void drawSettingsPage(); // page 1 void drawUnitsPage(); // page 2 void drawAlertPage(); // page 3 void drawCalibrationPage(); // page 4 void drawWifiPage(); // page 5 void drawTimedCountPage(); // page 6 void drawTimedCountRunningPage(int duration, int size); // page 7 void drawDeviceModePage(); // page 8 void drawFrame(); void drawBackButton(); void drawCancelButton(); void drawCloseButton(); void drawBlankDialogueBox(); long EEPROMReadlong(long address); void EEPROMWritelong(int address, long value); // logging functions void createJsonFile(); void clearLogs(); void setup() { Serial.begin(38400); ts.begin(); ts.setRotation(2); tft.begin(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); pinMode(D0, OUTPUT); // buzzer switch pinMode(D3, OUTPUT); // LED digitalWrite(D3, LOW); digitalWrite(D0, LOW); // EEPROM.begin(4096); // initialize ESP8266 emulated EEPROM sector with 4 kb doseUnits = EEPROM.read(saveUnits); alarmThreshold = EEPROM.read(saveAlertThreshold); conversionFactor = EEPROM.read(saveCalibration); deviceMode = EEPROM.read(saveDeviceMode); isLogging = EEPROM.read(saveLoggingMode); addr = EEPROMReadlong(96); // SSIDLength = EEPROM.read(saveSSIDLen); // passwordLength = EEPROM.read(savePWLen); // channelIDLength = EEPROM.read(saveIDLen); // writeAPILength = EEPROM.read(saveAPILen); // for (int i = 10; i < 10 + SSIDLength; i++) // { // ssid[i - 10] = EEPROM.read(i); // } // Serial.println(ssid); // // for (int j = 30; j < 30 + passwordLength; j++) // { // password[j - 30] = EEPROM.read(j); // } // Serial.println(password); // // for (int k = 50; k < 50 + channelIDLength; k++) // { // channelID[k - 50] = EEPROM.read(k); // } // Serial.println(channelID); // // for (int l = 70; l < 70 + writeAPILength; l++) // { // channelAPIkey[l - 70] = EEPROM.read(l); // } // Serial.println(channelAPIkey); attachInterrupt(interruptPin, isr, FALLING); drawHomePage(); // if (!deviceMode) // { // WiFi.mode( WIFI_OFF ); // turn off wifi // WiFi.forceSleepBegin(); // delay(1); // } // else { // WiFi.mode(WIFI_STA); // WiFi.begin(ssid, password); drawBlankDialogueBox(); tft.setTextSize(1); tft.setFont(&FreeSans9pt7b); tft.setTextColor(ILI9341_WHITE); tft.setCursor(38, 140); tft.println("Connecting to WiFi.."); // while ((WiFi.status() != WL_CONNECTED) && (attempts < 300)) // { // delay(100); // attempts ++; // } // if (attempts >= 300) // { // deviceMode = 0; // tft.setCursor(45, 200); // tft.println("Failed to connect."); // delay(1000); // } // else // { // tft.setCursor(68, 200); // tft.println("Connected!"); // delay(1000); // } drawHomePage(); } } void loop() { if (page == 0) // homepage { currentMillis = millis(); if (currentMillis - previousMillis >= 1000) { previousMillis = currentMillis; batteryUpdateCounter ++; if (batteryUpdateCounter == 30){ // update battery level every 30 seconds. Prevents random fluctations of battery level. batteryInput = analogRead(A0); batteryInput = constrain(batteryInput, 590, 800); batteryPercent = map(batteryInput, 590, 800, 0, 100); batteryMapped = map(batteryPercent, 100, 0, 212, 233); tft.fillRect(212, 6, 22, 10, ILI9341_BLACK); if (batteryPercent < 10) { tft.fillRect(batteryMapped, 6, (234 - batteryMapped), 10, ILI9341_RED); } else { tft.fillRect(batteryMapped, 6, (234 - batteryMapped), 10, ILI9341_GREEN); // draws battery icon } batteryUpdateCounter = 0; Serial.println(batteryInput); Serial.println(batteryPercent); } count[i] = currentCount; i++; fastCount[j] = currentCount; // keep concurrent arrays of counts. Use only one depending on user choice j++; slowCount[k] = currentCount; k++; if (i == 61) { i = 0; } if (j == 6) { j = 0; } if (k == 181) { k = 0; } if (integrationMode == 2) { averageCount = (currentCount - slowCount[k]) / 3; } if (integrationMode == 1) { averageCount = (currentCount - fastCount[j]) * 12; } else if (integrationMode == 0) { averageCount = currentCount - count[i]; // count[i] stores the value from 60 seconds ago } averageCount = ((averageCount) / (1 - 0.00000333 * float(averageCount))); // accounts for dead time of the geiger tube. relevant at high count rates if (doseUnits == 0) { doseRate = averageCount / float(conversionFactor); totalDose = cumulativeCount / (60 * float(conversionFactor)); } else if (doseUnits == 1) { doseRate = averageCount / float(conversionFactor * 10.0); totalDose = cumulativeCount / (60 * float(conversionFactor * 10.0)); // 1 mRem == 10 uSv } if (averageCount < conversionFactor/2) // 0.5 uSv/hr doseLevel = 0; // determines alert level displayed on homescreen else if (averageCount < alarmThreshold * conversionFactor) doseLevel = 1; else doseLevel = 2; if (doseRate < 10.0) { dtostrf(doseRate, 4, 2, dose); // display two digits after the decimal point if value is less than 10 } else if ((doseRate >= 10) && (doseRate < 100)) { dtostrf(doseRate, 4, 1, dose); // display one digit after decimal point when dose is greater than 10 } else if ((doseRate >= 100)) { dtostrf(doseRate, 4, 0, dose); // whole numbers only when dose is higher than 100 } else { dtostrf(doseRate, 4, 0, dose); // covers the rare edge case where the dose rate is sometimes errorenously calculated to be negative } tft.setFont(); tft.setCursor(44, 52); tft.setTextSize(5); tft.setTextColor(ILI9341_WHITE, DOSEBACKGROUND); tft.println(dose); // display effective dose rate tft.setTextSize(1); tft.setFont(); tft.setCursor(73, 122); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.setTextSize(3); tft.println(averageCount); // Display CPM if (averageCount < 10) { tft.fillRect(90, 120, 144, 25, ILI9341_BLACK); // erase numbers that may have been left from previous high readings } else if (averageCount < 100) { tft.fillRect(107, 120, 127, 25, ILI9341_BLACK); } else if (averageCount < 1000) { tft.fillRect(124, 120, 110, 25, ILI9341_BLACK); } else if (averageCount < 10000) { tft.fillRect(141, 120, 93, 25, ILI9341_BLACK); } else if (averageCount < 100000) { tft.fillRect(160, 120, 74, 25, ILI9341_BLACK); } tft.setCursor(80, 192); tft.setTextSize(2); tft.setTextColor(ILI9341_WHITE, 0x630C); tft.println(cumulativeCount); // display total counts since reset tft.setCursor(80, 222); tft.println(totalDose); // display cumulative dose if (doseLevel != previousDoseLevel) // only update alert level if it changed. This prevents flicker { if (doseLevel == 0) { tft.drawRect(0, 0, tft.width(), tft.height(), ILI9341_WHITE); tft.fillRoundRect(3, 94, 234, 21, 3, 0x2DC6); tft.setCursor(15, 104); tft.setFont(&FreeSans9pt7b); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); tft.println("NORMAL BACKGROUND"); previousDoseLevel = doseLevel; } else if (doseLevel == 1) { tft.drawRect(0, 0, tft.width(), tft.height(), ILI9341_WHITE); tft.fillRoundRect(3, 94, 234, 21, 3, 0xCE40); tft.setCursor(29, 104); tft.setFont(&FreeSans9pt7b); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); tft.println("ELEVATED ACTIVITY"); previousDoseLevel = doseLevel; } else if (doseLevel == 2) { tft.drawRect(0, 0, tft.width(), tft.height(), ILI9341_RED); tft.fillRoundRect(3, 94, 234, 21, 3, 0xB8A2); tft.setCursor(17, 104); tft.setFont(&FreeSans9pt7b); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); tft.println("HIGH RADIATION LEVEL"); previousDoseLevel = doseLevel; } } Serial.println(currentCount); } // end of millis()-controlled block that runs once every second. The rest of the code on page 0 runs every loop if (currentCount > previousCount) { if (ledSwitch) digitalWrite(D3, HIGH); // trigger buzzer and led if they are activated if (buzzerSwitch) digitalWrite(D0, HIGH); previousCount = currentCount; previousMicros = micros(); } currentMicros = micros(); if (currentMicros - previousMicros >= 200) { digitalWrite(D3, LOW); digitalWrite(D0, LOW); previousMicros = currentMicros; } if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) // A way of "debouncing" the touchscreen. Prevents multiple inputs from single touch { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); // get touch point and map to screen pixels y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 162 && x < 238) && (y > 259 && y < 318)) { integrationMode ++; if (integrationMode == 3) { integrationMode = 0; } currentCount = 0; previousCount = 0; for (int a = 0; a < 61; a++) // reset counts when integretation speed is changed { count[a] = 0; } for (int b = 0; b < 6; b++) { fastCount[b] = 0; } for (int c = 0; c < 181; c++) { slowCount[c] = 0; } if (integrationMode == 0) // change button based on touch and previous state { tft.fillRoundRect(162, 259, 74, 57, 3, 0x2A86); tft.setFont(&FreeSans12pt7b); tft.setTextSize(1); tft.setCursor(180, 283); tft.println("INT"); tft.setCursor(177, 309); tft.println("60 s"); } else if (integrationMode == 1) { tft.fillRoundRect(162, 259, 74, 57, 3, 0x2A86); tft.setFont(&FreeSans12pt7b); tft.setTextSize(1); tft.setCursor(180, 283); tft.println("INT"); tft.setCursor(184, 309); tft.println("5 s"); } else if (integrationMode == 2) { tft.fillRoundRect(162, 259, 74, 57, 3, 0x2A86); tft.setFont(&FreeSans12pt7b); tft.setTextSize(1); tft.setCursor(180, 283); tft.println("INT"); tft.setCursor(169, 309); tft.println("180 s"); } } else if ((x > 64 && x < 159) && (y > 259 && y < 318)) // timed count { page = 6; drawTimedCountPage(); } else if ((x > 190 && x < 238) && (y > 151 && y < 202)) // toggle LED { ledSwitch = !ledSwitch; if (ledSwitch) { tft.fillRoundRect(190, 151, 46, 51, 3, 0x6269); tft.drawBitmap(190, 153, ledOnBitmap, 45, 45, ILI9341_WHITE); } else { tft.fillRoundRect(190, 151, 46, 51, 3, 0x6269); tft.drawBitmap(190, 153, ledOffBitmap, 45, 45, ILI9341_WHITE); } } else if ((x > 190 && x < 238) && (y > 205 && y < 256)) // toggle buzzer { buzzerSwitch = !buzzerSwitch; if (buzzerSwitch) { tft.fillRoundRect(190, 205, 46, 51, 3, 0x6269); tft.drawBitmap(190, 208, buzzerOnBitmap, 45, 45, ILI9341_WHITE); } else { tft.fillRoundRect(190, 205, 46, 51, 3, 0x6269); tft.drawBitmap(190, 208, buzzerOffBitmap, 45, 45, ILI9341_WHITE); } } else if ((x > 3 && x < 61) && (y > 259 && y < 316)) // settings button pressed { page = 1; drawSettingsPage(); } } if (isLogging) { if(addr < 2100) { currentLogTime = millis(); if ((currentLogTime - previousLogTime) >= 600000) // log every 10 minutes { EEPROMWritelong(addr, averageCount); addr += 4; EEPROMWritelong(96, addr); // write current address number to an adress just before the logged data previousLogTime = currentLogTime; // EEPROM.commit(); // ESP8266 style } } } // if (deviceMode) // deviceMode is 1 when in monitoring station mode. Uploads CPM to thingspeak every 5 minutes // { // currentUploadTime = millis(); // if ((currentUploadTime - previousUploadTime) > 300000) // { // previousUploadTime = currentUploadTime; // if (client.connect(server, 80)) // { // String postStr = channelAPIkey; // postStr += "&field2="; // postStr += String(averageCount); // postStr += "\r\n\r\n"; // char temp[50] = "X-THINGSPEAKAPIKEY:"; // strcat(temp, channelAPIkey); // strcat(temp, "\n"); // client.print("POST /update HTTP/1.1\n"); // client.print("Host: api.thingspeak.com\n"); // client.print("Connection: close\n"); // client.print(temp); // client.print("Content-Type: application/x-www-form-urlencoded\n"); // client.print("Content-Length: "); // client.print(postStr.length()); // client.print("\n\n"); // client.print(postStr); // Serial.println(postStr); // } // client.stop(); // } // } // } // else if (page == 1) // settings page. all display elements are drawn when drawSettingsPage() is called { if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 4 && x < 62) && (y > 271 && y < 315)) // back button. draw homepage, reset counts and go back { currentCount = 0; previousCount = 0; for (int a = 0; a < 61; a++) { count[a] = 0; // counts need to be reset to prevent errorenous readings } for (int b = 0; b < 6; b++) { fastCount[b] = 0; } for (int c = 0; c < 181; c++) { slowCount[c] = 0; } page = 0; drawHomePage(); } else if ((x > 3 && x < 234) && (y > 64 && y < 108)) { page = 2; drawUnitsPage(); } else if ((x > 3 && x < 234) && (y > 114 && y < 158)) { page = 3; drawAlertPage(); } else if ((x > 3 && x < 234) && (y > 164 && y < 208)) { page = 4; drawCalibrationPage(); } else if ((x > 3 && x < 234) && (y > 214 && y < 268)) { page = 5; drawWifiPage(); } } } else if (page == 2) // units page { if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 4 && x < 62) && (y > 271 && y < 315)) // back button { page = 1; if (EEPROM.read(saveUnits) != doseUnits) // check current EEPROM value and only write if new value is different { EEPROM.write(saveUnits, doseUnits); // save current units to EEPROM during exit. This will be retrieved at startup // EEPROM.commit(); // ESP8266 style } drawSettingsPage(); } else if ((x > 4 && x < 234) && (y > 70 && y < 120)) { doseUnits = 0; tft.fillRoundRect(4, 71, 232, 48, 4, 0x2A86); tft.setCursor(30, 103); tft.println("Sieverts (uSv/hr)"); tft.fillRoundRect(4, 128, 232, 48, 4, ILI9341_BLACK); tft.setCursor(47, 160); tft.println("Rems (mR/hr)"); } else if ((x > 4 && x < 234) && (y > 127 && y < 177)) { doseUnits = 1; tft.fillRoundRect(4, 71, 232, 48, 4, ILI9341_BLACK); tft.setCursor(30, 103); tft.println("Sieverts (uSv/hr)"); tft.fillRoundRect(4, 128, 232, 48, 4, 0x2A86); tft.setCursor(47, 160); tft.println("Rems (mR/hr)"); } } } else if (page == 3) // alert thresold page { tft.setFont(); tft.setTextSize(3); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.setCursor(151, 146); tft.println(alarmThreshold); if (alarmThreshold < 10) tft.fillRect(169, 146, 22, 22, ILI9341_BLACK); if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 4 && x < 62) && (y > 271 && y < 315)) { page = 1; if (EEPROM.read(saveAlertThreshold) != alarmThreshold) { EEPROM.write(saveAlertThreshold, alarmThreshold); // EEPROM.commit(); // ESP8266-style save to EEPROM to be retrieved at startup } drawSettingsPage(); } else if ((x > 130 && x < 190) && (y > 70 && y < 120)) { alarmThreshold++; if (alarmThreshold > 100) alarmThreshold = 100; } else if ((x > 130 && x < 190) && (y > 185 && y < 245)) { alarmThreshold--; if (alarmThreshold <= 2) alarmThreshold = 2; } } } else if (page == 4) // calibration page { tft.setFont(); tft.setTextSize(3); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.setCursor(161, 146); tft.println(conversionFactor); if (conversionFactor < 100) tft.fillRect(197, 146, 22, 22, ILI9341_BLACK); if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 4 && x < 62) && (y > 271 && y < 315)) { page = 1; if (EEPROM.read(saveCalibration) != conversionFactor) { EEPROM.write(saveCalibration, conversionFactor); // EEPROM.commit(); // ESP8266 style } drawSettingsPage(); } else if ((x > 160 && x < 220) && (y > 70 && y < 120)) { conversionFactor++; } else if ((x > 160 && x < 220) && (y > 185 && y < 245)) { conversionFactor--; if (conversionFactor <= 1) conversionFactor = 1; } } } else if (page == 5) // Wifi page { if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 4 && x < 62) && (y > 271 && y < 315)) { page = 1; if (EEPROM.read(saveLoggingMode) != isLogging) // check current EEPROM value and only write if new value is different { EEPROM.write(saveLoggingMode, isLogging); // EEPROM.commit(); // ESP8266 style } drawSettingsPage(); } else if ((x > 3 && x < 237) && (y > 64 && y < 108)) // wifi setup button { tft.setFont(&FreeSans9pt7b); tft.setTextSize(1); tft.fillRoundRect(10, 30, 220, 260, 6, ILI9341_BLACK); tft.drawRoundRect(10, 30, 220, 260, 6, ILI9341_WHITE); tft.setCursor(50, 50); tft.println("AP SETUP MODE"); tft.drawFastHLine(50, 53, 145, ILI9341_WHITE); tft.setCursor(20, 80); tft.println("With any WiFi capable"); tft.setCursor(20, 100); tft.println("device, connect to"); tft.setCursor(20, 120); tft.println("network \"GC20\" and "); tft.setCursor(20, 140); tft.println("browse to 192.168.4.1"); tft.setCursor(20, 160); tft.println("Enter credentials"); tft.setCursor(20, 180); tft.println("of your WiFi network"); tft.setCursor(20, 200); tft.println("and the Channel ID and"); tft.setCursor(20, 220); tft.println("write API key of your"); tft.setCursor(20, 240); tft.println("ThingSpeak channel"); delay(100); // WiFiManager wifiManager; // // char channelIDSt[20]; // char writeAPISt[20]; // // WiFiManagerParameter channel_id("0", "Channel ID", channelIDSt, 20); // create custom parameters for setup // // WiFiManagerParameter write_api("1", "Write API", writeAPISt, 20); // wifiManager.addParameter(&channel_id); // wifiManager.addParameter(&write_api); // // wifiManager.startConfigPortal("GC20"); // put the esp in AP mode for wifi setup, create a network with name "GC20" // // strcpy(channelIDSt, channel_id.getValue()); // strcpy(writeAPISt, write_api.getValue()); // // size_t idLen = String(channelIDSt).length(); // // size_t apiLen = String(writeAPISt).length(); // // char channelInit = EEPROM.read(4001); // first character of channelID is stored in EEPROM address 4001 // char apiKeyInit = EEPROM.read(4002); // Only overwrite channelIDSt and writeAPISt if new value of the first character is different from what was saved. // // if (channelInit != channelIDSt[0]) // { // for (unsigned int a = 50; a < 50 + idLen; a++) // { // EEPROM.write((a), channelIDSt[a - 50]); // } // EEPROM.write(saveIDLen, idLen); // } // // if(apiKeyInit != writeAPISt[0]) // { // for (unsigned int b = 70; b < 70 + apiLen; b++) // { // EEPROM.write((b), writeAPISt[b - 70]); // } // EEPROM.write(saveAPILen, apiLen); // } // String ssidString = WiFi.SSID(); // retrieve ssid and password form the WifiManager library // String passwordString = WiFi.psk(); // // size_t ssidLen = ssidString.length(); // size_t passLen = passwordString.length(); // // Serial.println(ssidLen); // Serial.println(passLen); // // char ssidChar[20]; // char passwordChar[20]; // // ssidString.toCharArray(ssidChar, ssidLen + 1); // passwordString.toCharArray(passwordChar, passLen + 1); // // for (unsigned int a = 10; a < 10 + ssidLen; a++) // { // EEPROM.write((a), ssidChar[a - 10]); // save ssid and ssid length to EEPROM // } // EEPROM.write(saveSSIDLen, ssidLen); // // for (unsigned int b = 30; b < 30 + passLen; b++) // { // EEPROM.write((b), passwordChar[b - 30]); // save password and password length to EEPROM // } // EEPROM.write(savePWLen, passLen); // // EEPROM.write(4001, channelIDSt[0]); // save first characters of channel ID and api key to EEPROM // EEPROM.write(4002, writeAPISt[0]); // // EEPROM.commit(); tft.setCursor(16, 265); tft.println("Settings saved. Restarting"); delay(1000); // ESP.reset(); } else if ((x > 3 && x < 237) && (y > 162 && y < 206)) // upload data { drawBlankDialogueBox(); // tft.setCursor(38, 100); // tft.println("Connecting to Wifi.."); // delay(100); // Serial.println(ssid); // Serial.println(password); // WiFi.begin(ssid, password); // // while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect // delay(100); // } // // tft.setCursor(36, 160); // tft.println("Creating JSON file.."); // createJsonFile(); // reads logged data from EEPROM and creates a json file // Serial.println(jsonBuffer); // delay(1000); // tft.setCursor(70, 220); // tft.println("Uploading.."); // delay(1000); // // char secondHalf[50] = "\",\"updates\":"; // strcat(data, channelAPIkey); // strcat(data, secondHalf); // // strcat(data,jsonBuffer); // concatenate strings together and store in array named data // strcat(data,"}"); // // Serial.println(data); // // client.stop(); // String data_length = String(strlen(data)+1); // // if (client.connect(server, 80)) { // post data to thingspeak // char temp1[100] = "POST /channels/"; // char temp2[30] = "/bulk_update.json HTTP/1.1"; // // strcat(temp1, channelID); // strcat(temp1, temp2); // // client.println(temp1); // client.println("Host: api.thingspeak.com"); // client.println("User-Agent: mw.doc.bulk-update (Arduino ESP8266)"); // client.println("Connection: close"); // client.println("Content-Type: application/json"); // client.println("Content-Length: "+data_length); // client.println(); // client.println(data); // client.stop(); // // WiFi.disconnect(); // WiFi.mode( WIFI_OFF ); // turn off wifi // WiFi.forceSleepBegin(); // delay(1); clearLogs(); // erase logs and re-initialize the json buffer tft.setCursor(43, 260); tft.println("Resetting Device.."); delay(1000); // ESP.reset(); } else { tft.setCursor(50, 260); tft.println("Failed to upload"); delay(1000); // ESP.reset(); } } else if ((x > 3 && x < 237) && (y > 114 && y < 158)) // logging { isLogging = !isLogging; if (isLogging) { tft.fillRoundRect(3, 114, 234, 44, 4, 0x3B8F); tft.drawRoundRect(3, 114, 234, 44, 4, WHITE); tft.setCursor(38, 145); tft.println("LOGGING ON"); } else { tft.fillRoundRect(3, 114, 234, 44, 4, 0xB9C7); tft.drawRoundRect(3, 114, 234, 44, 4, WHITE); tft.setCursor(33, 145); tft.println("LOGGING OFF"); } } else if ((x > 3 && x < 237) && (y > 214 && y < 258)) // device mode { page = 8; drawDeviceModePage(); } } } else if (page == 6) // timed count setup page { if (interval < 10) { intervalSize = 1; } else if (interval < 100) { intervalSize = 2; } else { intervalSize = 3; } tft.setFont(); tft.setTextSize(3); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.setCursor((185 - (intervalSize - 1) * 11), 146); tft.println(interval); if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 4 && x < 62) && (y > 271 && y < 315)) { page = 0; drawHomePage(); currentCount = 0; previousCount = 0; for (int a = 0; a < 60; a++) { count[a] = 0; // counts need to be reset to prevent errorenous readings } for (int b = 0; b < 5; b++) { fastCount[b] = 0; } for (int c = 0; c < 180; c++) { slowCount[c] = 0; } } else if ((x > 145 && x < 235) && (y > 271 && y < 315)) { page = 7; drawTimedCountRunningPage(interval, intervalSize); } else if ((x > 160 && x < 220) && (y > 70 && y < 120)) { interval += 5; if (interval >= 995) { interval = 995; } tft.fillRect(160, 130, 70, 40, ILI9341_BLACK); } else if ((x > 160 && x < 220) && (y > 185 && y < 245)) { interval -= 5; if (interval <= 5) { interval = 5; } tft.fillRect(160, 130, 70, 40, ILI9341_BLACK); } } } else if (page == 7) // timed count running page { elapsedTime = millis() - startMillis; if(elapsedTime < intervalMillis) { if((millis() - previousMillis) >= 1000) { previousMillis = millis(); tft.setFont(); tft.setTextSize(3); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.setCursor(101, 181); tft.println(currentCount); cpm = float(currentCount) / float((1 + elapsedTime) / 60000.0); tft.setCursor(101, 226); tft.println(cpm); if(cpm < 10) { tft.fillRect(170, 225, 50, 40, ILI9341_BLACK); } else if(cpm < 100) { tft.fillRect(190, 225, 35, 40, ILI9341_BLACK); } else if(cpm < 1000) { tft.fillRect(209, 225, 18, 40, ILI9341_BLACK); } } progress = map(elapsedTime, 0, intervalMillis, 0, 217); tft.fillRect(12, 105, progress, 16, 0x25A6); } else { if (completed == 0) { drawCloseButton(); completed = 1; } } if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 70 && x < 170) && (y > 271 && y < 315)) { page = 0; drawHomePage(); currentCount = 0; previousCount = 0; for (int a = 0; a < 60; a++) { count[a] = 0; // counts need to be reset to prevent errorenous readings } for (int b = 0; b < 5; b++) { fastCount[b] = 0; } for (int c = 0; c < 180; c++) { slowCount[c] = 0; } } } } else if (page == 8) // device mode selection page { if (!ts.touched()) wasTouched = 0; if (ts.touched() && !wasTouched) { wasTouched = 1; TS_Point p = ts.getPoint(); x = map(p.x, TS_MINX, TS_MAXX, 240, 0); y = map(p.y, TS_MINY, TS_MAXY, 320, 0); if ((x > 4 && x < 62) && (y > 271 && y < 315)) // back button { page = 5; if (EEPROM.read(saveDeviceMode) != deviceMode) // check current EEPROM value and only write if new value is different { EEPROM.write(saveDeviceMode, deviceMode); // EEPROM.commit(); } drawWifiPage(); } else if ((x > 4 && x < 234) && (y > 70 && y < 120)) { deviceMode = 0; tft.setFont(&FreeSans12pt7b); tft.fillRoundRect(4, 71, 232, 48, 4, 0x2A86); tft.setCursor(13, 103); tft.println("GEIGER COUNTER"); tft.fillRoundRect(4, 128, 232, 48, 4, ILI9341_BLACK); tft.setCursor(30, 160); tft.println("MON. STATION"); } else if ((x > 4 && x < 234) && (y > 127 && y < 177)) { deviceMode = 1; tft.setFont(&FreeSans12pt7b); tft.fillRoundRect(4, 71, 232, 48, 4, ILI9341_BLACK); tft.setCursor(13, 103); tft.println("GEIGER COUNTER"); tft.fillRoundRect(4, 128, 232, 48, 4, 0x2A86); tft.setCursor(30, 160); tft.println("MON. STATION"); } } } } void drawHomePage() { tft.fillRect(1, 21, 237, 298, ILI9341_BLACK); tft.drawRect(0, 0, tft.width(), tft.height(), ILI9341_WHITE); tft.drawRoundRect(210, 4, 26, 14, 3, ILI9341_WHITE); tft.drawLine(209, 8, 209, 13, ILI9341_WHITE); // Battery symbol tft.drawLine(208, 8, 208, 13, ILI9341_WHITE); tft.fillRect(212, 6, 22, 10, ILI9341_BLACK); tft.fillRect(batteryMapped, 6, (234 - batteryMapped), 10, ILI9341_GREEN); tft.setTextSize(1); tft.setTextColor(ILI9341_CYAN); tft.setFont(&FreeSans9pt7b); tft.setCursor(2, 16); tft.println("GC-20"); tft.setTextColor(ILI9341_WHITE); tft.setFont(); tft.setTextSize(2); tft.setCursor(118, 4); tft.println("+"); tft.setTextSize(1); tft.setFont(&FreeSans9pt7b); tft.drawBitmap(103, 2, betaBitmap, 18, 18, ILI9341_WHITE); tft.drawBitmap(128, 2, gammaBitmap, 12, 18, ILI9341_WHITE); tft.drawLine(1, 20, 238, 20, ILI9341_WHITE); tft.fillRoundRect(3, 23, 234, 69, 3, DOSEBACKGROUND); tft.setCursor(16, 40); tft.println("EFFECTIVE DOSE RATE:"); tft.setCursor(165, 85); tft.setFont(&FreeSans12pt7b); if (doseUnits == 0) { tft.println("uSv/hr"); } else if (doseUnits == 1) { tft.println("mR/hr"); } tft.fillRoundRect(3, 94, 234, 21, 3, 0x2DC6); tft.setCursor(15, 110); tft.setFont(&FreeSans9pt7b); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); tft.println("NORMAL BACKGROUND"); tft.setFont(&FreeSans12pt7b); tft.setCursor(7, 141); tft.println("CPM:"); tft.drawRoundRect(3, 117, 234, 32, 3, DOSEBACKGROUND); tft.fillRoundRect(3, 151, 185, 105, 4, 0x630C); tft.setFont(&FreeSans9pt7b); tft.setCursor(9, 171); tft.println("CUMULATIVE DOSE"); tft.setCursor(7, 205); tft.println("Counts:"); if (doseUnits == 0) { tft.setCursor(34, 235); tft.println("uSv:"); } else if (doseUnits == 1) { tft.setCursor(37, 235); tft.println("mR:"); } tft.fillRoundRect(3, 259, 58, 57, 3, 0x3B8F); tft.drawBitmap(1, 257, settingsBitmap, 60, 60, ILI9341_WHITE); tft.fillRoundRect(64, 259, 95, 57, 3, 0x6269); tft.setFont(&FreeSans12pt7b); tft.setTextSize(1); tft.setCursor(74, 284); tft.println("TIMED"); tft.setCursor(70, 309); tft.println("COUNT"); if (integrationMode == 0) { tft.fillRoundRect(162, 259, 74, 57, 3, 0x2A86); tft.setCursor(180, 283); tft.println("INT"); tft.setCursor(177, 309); tft.println("60 s"); } else if (integrationMode == 1) { tft.fillRoundRect(162, 259, 74, 57, 3, 0x2A86); tft.setCursor(180, 283); tft.println("INT"); tft.setCursor(184, 309); tft.println("5 s"); } else if (integrationMode == 2) { tft.fillRoundRect(162, 259, 74, 57, 3, 0x2A86); tft.setCursor(180, 283); tft.println("INT"); tft.setCursor(169, 309); tft.println("180 s"); } if (ledSwitch) { tft.fillRoundRect(190, 151, 46, 51, 3, 0x6269); tft.drawBitmap(190, 153, ledOnBitmap, 45, 45, ILI9341_WHITE); } else if (!ledSwitch) { tft.fillRoundRect(190, 151, 46, 51, 3, 0x6269); tft.drawBitmap(190, 153, ledOffBitmap, 45, 45, ILI9341_WHITE); } if (buzzerSwitch) { tft.fillRoundRect(190, 205, 46, 51, 3, 0x6269); tft.drawBitmap(190, 208, buzzerOnBitmap, 45, 45, ILI9341_WHITE); } else if (!buzzerSwitch) { tft.fillRoundRect(190, 205, 46, 51, 3, 0x6269); tft.drawBitmap(190, 208, buzzerOffBitmap, 45, 45, ILI9341_WHITE); } tft.setFont(&FreeSans9pt7b); if (isLogging) { tft.setCursor(175, 16); tft.println("L"); } else { tft.fillRect(175, 2, 18, 18, ILI9341_BLACK); } if (deviceMode) { tft.drawBitmap(188, 1, wifiBitmap, 19, 19, ILI9341_WHITE); } else { tft.fillRect(188, 1, 19, 19, ILI9341_BLACK); } } void drawSettingsPage() { digitalWrite(D3, LOW); digitalWrite(D0, LOW); drawFrame(); tft.fillRoundRect(3, 23, 234, 35, 3, 0x3B8F); tft.setFont(&FreeSans12pt7b); tft.setCursor(57, 48); tft.println("SETTINGS"); tft.drawFastHLine(59, 51, 117, WHITE); tft.fillRoundRect(3, 64, 234, 44, 4, 0x2A86); tft.drawRoundRect(3, 64, 234, 44, 4, WHITE); tft.setCursor(44, 94); tft.println("DOSE UNITS"); tft.fillRoundRect(3, 114, 234, 44, 4, 0x2A86); tft.drawRoundRect(3, 114, 234, 44, 4, WHITE); tft.setCursor(5, 145); tft.println("ALERT THRESHOLD"); tft.fillRoundRect(3, 164, 234, 44, 4, 0x2A86); tft.drawRoundRect(3, 164, 234, 44, 4, WHITE); tft.setCursor(37, 194); tft.println("CALIBRATION"); tft.fillRoundRect(3, 214, 234, 44, 4, 0x2A86); tft.drawRoundRect(3, 214, 234, 44, 4, WHITE); tft.setCursor(8, 244); tft.println("LOGGING AND WIFI"); drawBackButton(); } void drawUnitsPage() { drawFrame(); tft.fillRoundRect(3, 23, 234, 40, 3, 0x3B8F); tft.setFont(&FreeSans12pt7b); tft.setCursor(84, 51); tft.println("UNITS"); tft.drawFastHLine(86, 55, 71, WHITE); drawBackButton(); tft.drawRoundRect(3, 70, 234, 50, 4, WHITE); if (doseUnits == 0) tft.fillRoundRect(4, 71, 232, 48, 4, 0x2A86); tft.setCursor(30, 103); tft.println("Sieverts (uSv/hr)"); tft.drawRoundRect(3, 127, 234, 50, 4, WHITE); if (doseUnits == 1) tft.fillRoundRect(4, 128, 232, 48, 4, 0x2A86); tft.setCursor(47, 160); tft.println("Rems (mR/hr)"); } void drawAlertPage() { drawFrame(); tft.fillRoundRect(3, 23, 234, 40, 3, 0x3B8F); tft.setFont(&FreeSans12pt7b); tft.setCursor(4, 51); tft.println("ALERT THRESHOLD"); tft.drawFastHLine(5, 55, 229, WHITE); drawBackButton(); tft.setCursor(30, 164); tft.println("uSv/hr:"); tft.drawRoundRect(130, 70, 60, 60, 4, ILI9341_WHITE); tft.fillRoundRect(131, 71, 58, 58, 4, 0x2A86); tft.drawRoundRect(130, 185, 60, 60, 4, ILI9341_WHITE); tft.fillRoundRect(131, 186, 58, 58, 4, 0x2A86); tft.setCursor(140, 113); tft.setTextSize(3); tft.println("+"); tft.setCursor(148, 232); tft.println("-"); tft.setTextSize(1); } void drawCalibrationPage() { drawFrame(); tft.fillRoundRect(3, 23, 234, 40, 3, 0x3B8F); tft.setFont(&FreeSans12pt7b); tft.setCursor(47, 51); tft.println("CALIBRATE"); tft.drawFastHLine(48, 55, 133, WHITE); drawBackButton(); tft.setFont(&FreeSans9pt7b); tft.setCursor(8, 154); tft.println("Conversion Factor"); tft.setCursor(8, 174); tft.println("(CPM per uSv/hr)"); tft.drawRoundRect(160, 70, 60, 60, 4, ILI9341_WHITE); tft.fillRoundRect(161, 71, 58, 58, 4, 0x2A86); tft.drawRoundRect(160, 185, 60, 60, 4, ILI9341_WHITE); tft.fillRoundRect(161, 186, 58, 58, 4, 0x2A86); tft.setCursor(170, 113); tft.setFont(&FreeSans12pt7b); tft.setTextSize(3); tft.println("+"); tft.setCursor(178, 232); tft.println("-"); tft.setTextSize(1); } void drawWifiPage() { drawFrame(); drawBackButton(); tft.fillRoundRect(3, 23, 234, 35, 3, 0x3B8F); tft.setFont(&FreeSans12pt7b); tft.setCursor(7, 48); tft.println("LOGGING AND WIFI"); tft.drawFastHLine(8, 51, 222, WHITE); tft.fillRoundRect(3, 64, 234, 44, 4, 0x2A86); tft.drawRoundRect(3, 64, 234, 44, 4, WHITE); tft.setCursor(48, 94); tft.println("WIFI SETUP"); if (isLogging) { tft.fillRoundRect(3, 114, 234, 44, 4, 0x3B8F); tft.drawRoundRect(3, 114, 234, 44, 4, WHITE); tft.setCursor(38, 145); tft.println("LOGGING ON"); } else { tft.fillRoundRect(3, 114, 234, 44, 4, 0xB9C7); tft.drawRoundRect(3, 114, 234, 44, 4, WHITE); tft.setCursor(33, 145); tft.println("LOGGING OFF"); } tft.fillRoundRect(3, 164, 234, 44, 4, 0x2A86); tft.drawRoundRect(3, 164, 234, 44, 4, WHITE); tft.setCursor(31, 194); tft.println("UPLOAD DATA"); tft.fillRoundRect(3, 214, 234, 44, 4, 0x2A86); tft.drawRoundRect(3, 214, 234, 44, 4, WHITE); tft.setCursor(35, 244); tft.println("DEVICE MODE"); if (addr > 2000) { tft.setFont(&FreeSans9pt7b); tft.setCursor(80, 297); tft.println("Log memory full"); } } void drawTimedCountPage() { drawFrame(); drawBackButton(); tft.fillRoundRect(145, 271, 92, 45, 3, 0x3B8F); tft.drawRoundRect(145, 271, 92, 45, 3, ILI9341_WHITE); tft.setFont(&FreeSans12pt7b); tft.setCursor(149, 302); tft.println("BEGIN!"); tft.fillRoundRect(3, 23, 234, 40, 3, 0x3B8F); tft.setCursor(34, 51); tft.println("TIMED COUNT"); tft.drawFastHLine(35, 55, 163, WHITE); tft.setFont(&FreeSans9pt7b); tft.setCursor(5, 162); tft.println("Duration (minutes):"); tft.drawRoundRect(160, 70, 60, 60, 4, ILI9341_WHITE); tft.fillRoundRect(161, 71, 58, 58, 4, 0x2A86); tft.drawRoundRect(160, 185, 60, 60, 4, ILI9341_WHITE); tft.fillRoundRect(161, 186, 58, 58, 4, 0x2A86); tft.setCursor(170, 113); tft.setFont(&FreeSans12pt7b); tft.setTextSize(3); tft.println("+"); tft.setCursor(178, 232); tft.println("-"); tft.setTextSize(1); cpm = 0; progress = 0; } void drawTimedCountRunningPage(int duration, int size) { drawFrame(); drawCancelButton(); tft.fillRoundRect(3, 23, 234, 40, 3, 0x3B8F); tft.setFont(&FreeSans12pt7b); tft.setTextSize(1); tft.setCursor(34, 51); tft.println("TIMED COUNT"); tft.drawFastHLine(35, 55, 163, WHITE); tft.drawRoundRect(3, 66, 234, 95, 4, ILI9341_WHITE); tft.drawRect(10, 103, 220, 20, ILI9341_WHITE); tft.drawRoundRect(3, 164, 234, 103, 4, ILI9341_WHITE); tft.setCursor(58, 90); tft.println("Progress:"); tft.setCursor(13, 150); tft.println("Duration:"); tft.setCursor(115, 150); tft.println(duration); tft.setCursor((135 + (size - 1)*15), 150); tft.println("min"); tft.setCursor(15, 200); tft.println("Counts:"); tft.setCursor(37, 245); tft.println("CPM:"); currentCount = 0; startMillis = millis(); intervalMillis = duration * 60000; completed = 0; } void drawDeviceModePage() { drawFrame(); tft.fillRoundRect(3, 23, 234, 40, 3, 0x3B8F); tft.setFont(&FreeSans12pt7b); tft.setCursor(34, 51); tft.println("DEVICE MODE"); tft.drawFastHLine(35, 57, 160, WHITE); drawBackButton(); tft.drawRoundRect(3, 70, 234, 50, 4, WHITE); if (deviceMode == 0) tft.fillRoundRect(4, 71, 232, 48, 4, 0x2A86); tft.setCursor(13, 103); tft.println("GEIGER COUNTER"); tft.drawRoundRect(3, 127, 234, 50, 4, WHITE); if (deviceMode == 1) tft.fillRoundRect(4, 128, 232, 48, 4, 0x2A86); tft.setCursor(30, 160); tft.println("MON. STATION"); tft.setFont(&FreeSans9pt7b); tft.setCursor(20, 200); tft.println("Press Back button and"); tft.setCursor(20, 220); tft.println("reset device for changes"); tft.setCursor(20, 240); tft.println("to take effect"); } void isr() // interrupt service routine { if ((micros() - 200) > previousIntMicros){ currentCount++; cumulativeCount++; } previousIntMicros = micros(); } void drawBackButton(){ tft.fillRoundRect(4, 271, 62, 45, 3, 0x3B8F); tft.drawRoundRect(4, 271, 62, 45, 3, ILI9341_WHITE); tft.drawBitmap(4, 271, backBitmap, 62, 45, ILI9341_WHITE); } void drawFrame(){ tft.fillRect(2, 21, 236, 298, ILI9341_BLACK); tft.drawRect(0, 0, tft.width(), tft.height(), ILI9341_WHITE); tft.drawRoundRect(210, 4, 26, 14, 3, ILI9341_WHITE); tft.drawLine(209, 8, 209, 13, ILI9341_WHITE); // Battery symbol tft.drawLine(208, 8, 208, 13, ILI9341_WHITE); tft.fillRect(212, 6, 22, 10, ILI9341_BLACK); tft.fillRect(batteryMapped, 6, (234 - batteryMapped), 10, ILI9341_GREEN); tft.setFont(&FreeSans9pt7b); tft.setCursor(2, 16); tft.setTextColor(ILI9341_CYAN); tft.setTextSize(1); tft.println("GC-20"); tft.setTextColor(ILI9341_WHITE); tft.setFont(); tft.setTextSize(2); tft.setCursor(118, 4); tft.println("+"); tft.setTextSize(1); tft.setFont(&FreeSans9pt7b); tft.drawBitmap(103, 2, betaBitmap, 18, 18, ILI9341_WHITE); tft.drawBitmap(128, 2, gammaBitmap, 12, 18, ILI9341_WHITE); tft.drawLine(1, 20, 238, 20, ILI9341_WHITE); tft.setFont(&FreeSans9pt7b); if (isLogging) { tft.setCursor(175, 16); tft.println("L"); } else { tft.fillRect(175, 2, 18, 18, ILI9341_BLACK); } if (deviceMode) { tft.drawBitmap(188, 1, wifiBitmap, 18, 18, ILI9341_WHITE); } else { tft.fillRect(188, 1, 19, 19, ILI9341_BLACK); } } void drawCancelButton() { tft.fillRoundRect(70, 271, 100, 45, 3, 0xB9C7); tft.drawRoundRect(70, 271, 100, 45, 3, ILI9341_WHITE); tft.setFont(&FreeSans12pt7b); tft.setCursor(72, 302); tft.println("CANCEL"); } void drawCloseButton() { tft.fillRoundRect(70, 271, 100, 45, 3, 0x3B8F); tft.drawRoundRect(70, 271, 100, 45, 3, ILI9341_WHITE); tft.setTextSize(1); tft.setFont(&FreeSans12pt7b); tft.setCursor(79, 302); tft.println("CLOSE"); } long EEPROMReadlong(long address) { long four = EEPROM.read(address); long three = EEPROM.read(address + 1); long two = EEPROM.read(address + 2); long one = EEPROM.read(address + 3); return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF); } void EEPROMWritelong(int address, long value) { byte four = (value & 0xFF); byte three = ((value >> 8) & 0xFF); byte two = ((value >> 16) & 0xFF); byte one = ((value >> 24) & 0xFF); EEPROM.write(address, four); EEPROM.write(address + 1, three); EEPROM.write(address + 2, two); EEPROM.write(address + 3, one); } void createJsonFile() { Serial.println(addr); for (int i = 100; i < addr; i += 4) { int count = EEPROMReadlong(i); int deltaT = 600; strcat(jsonBuffer,"{\"delta_t\":"); size_t lengthT = String(deltaT).length(); char temp[10]; String(deltaT).toCharArray(temp,lengthT + 1); strcat(jsonBuffer,temp); strcat(jsonBuffer,","); strcat(jsonBuffer, "\"field1\":"); lengthT = String(count).length(); String(count).toCharArray(temp, lengthT + 1); strcat(jsonBuffer,temp); strcat(jsonBuffer,"},"); } size_t len = strlen(jsonBuffer); jsonBuffer[len-1] = ']'; } void drawBlankDialogueBox() { tft.setFont(&FreeSans9pt7b); tft.setTextSize(1); tft.fillRoundRect(20, 50, 200, 220, 6, ILI9341_BLACK); tft.drawRoundRect(20, 50, 200, 220, 6, ILI9341_WHITE); } void clearLogs() { for (int j = 100; j < 4000; j ++) { EEPROMWritelong(j, 0); } for (int k = 1; k < 1000; k++) // keep the first character in jsonBuffer: "[" { jsonBuffer[k] = 0; } addr = 100; EEPROMWritelong(96, addr); EEPROM.write(saveLoggingMode, 0); // EEPROM.commit(); isLogging = 0; } Obrigado e feliz Halloween a todos!
  13. Boas tardes, ainda não tive tempo para conhecer melhor os amplificadores operacionais, porém descobri este vídeo do youtube em que o autor cria um circuito simples e consegue baixar a tensão até 0.2V, é mais ou menos isso que eu vou tentar fazer, porém quero também restringir a corrente máxima (além da tensão também ser mais alta do que eu gostaria). Será que também não podia montar algo semelhante? Obrigado a todos. vídeo:

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...