Ir ao conteúdo
  • Cadastre-se

Thiago Felipe Soares Gonçalves

Membro Pleno
  • Posts

    86
  • Cadastrado em

  • Última visita

Tudo que Thiago Felipe Soares Gonçalves postou

  1. Boa Noite, estou trabalhando em um projeto com o objetivo de fazer um relógio usando NodeMCU com sincronização da hora usando NTP. porém estou com algum erro no código que usei para fazer a sincronização estão dando horário totalmente diferentes e como não entendo muito de NTP queria ajuda para encontrar o problema. Segue o código utilizado. #include <NTPClient.h>//Biblioteca do NTP. #include <WiFiUdp.h>//Biblioteca do UDP. #include <ESP8266WiFi.h>//Biblioteca do WiFi. WiFiUDP udp;//Cria um objeto "UDP". NTPClient ntp(udp, "pool.ntp.br", -3 * 3600, 60000);//Cria um objeto "NTP" com as configurações. #define led D4//Define o LED ao pino D4. String hora;//Váriavel que armazenara o horario do NTP. void setup() { Serial.begin(9600);//Inicia a comunicação serial. pinMode(led, OUTPUT);//Define o pino como saida. digitalWrite(led, 1);//Apaga o LED. WiFi.mode(WIFI_STA); WiFi.begin("Copel71", "36927100");//Conecta ao WiFi. delay(2000);//Espera a conexão. ntp.begin();//Inicia o NTP. ntp.forceUpdate();//Força o Update. } void loop() { hora = ntp.getFormattedTime();//Armazena na váriavel HORA, o horario atual. Serial.println(hora);//Printa a hora já formatada no monitor. if (hora == "19:23:30")//Se a hora atual for igual à que definimos, irá acender o led. { digitalWrite(led, 0);//Acende } delay(1000);//Espera 1 segundo. } O horário que fiz o teste era 20:01 porém o print do NodeMCU mostra 03:52.
  2. Boa Tarde, estou com dificuldades para gravar um modulo wifi ESP8266. Já havia gravado este mesmo modulo varias vezes sem problemas mas recentemente ele esta me dando problemas. Segue a mensagem de erro na IDE Arduíno. Opções de compilação alteradas, recompilando tudo Archiving built core (caching) in: C:\Users\thiag\AppData\Local\Temp\arduino_cache_188028\core\core_esp8266_esp8266_generic_CpuFrequency_80,ResetMethod_ck,CrystalFreq_26,FlashFreq_40,FlashMode_qio,FlashSize_512K64,led_2,LwIPVariant_v2mss536,Debug_Disabled,DebugLevel_None____,FlashErase_none,UploadSpeed_115200_dd55652ebf349e7e4b3ae6f8c7553307.a O sketch usa 266776 bytes (61%) de espaço de armazenamento para programas. O máximo são 434160 bytes. Variáveis globais usam 34980 bytes (42%) de memória dinâmica, deixando 46940 bytes para variáveis locais. O máximo são 81920 bytes. warning: espcomm_send_command: wrong direction/command: 0x01 0x03, expected 0x01 0x08 Uploading 270928 bytes from C:\Users\thiag\AppData\Local\Temp\arduino_build_987917/teste_lumi.ino.bin to flash at 0x00000000 ................................................................................ [ 30% ] ................................................................................ [ 60% ] ................................................................................ [ 90% ] ........................warning: espcomm_send_command: didn't receive command response warning: espcomm_send_command(FLASH_DOWNLOAD_DATA) failed warning: espcomm_send_command: wrong direction/command: 0x01 0x03, expected 0x01 0x04 error: espcomm_upload_mem failed error: espcomm_upload_mem failed Enfim, não sei o que pode estar gerando esse problema, já que estou com atualização em dia e o mesmo código é gravado sem problemas no NodeMCU. Enfim, se alguém poder me dar uma luz.
  3. Vi só agora @Isadora Ferraz, vou testar do seu jeito, estou tendo outros problemas no projeto tipo estou de variável kkkkkk umas incompatibilidades loucas nem sei explicar direito.
  4. Consegui resolver o problema ontem de madrugada, aumentei o clock de 4Mhz para 16Mhz, alem disso fiz uma instrução parecida com o que a @Isadora Ferraz mostrou. Alias o microcontrolador que estou usando é um ATMEGA328P e o que estou fazendo é um pov com velocidade variável, fazendo a projeção manter sua forma mesmo alterando a velocidade de rotação. data = 0b01001001; if(data & 0b00000001) setb(PB4); else clrb(PB4); if(data & 0b00000010) setb(PB3); else clrb(PB3); if(data & 0b00000100) setb(PB2); else clrb(PB2); if(data & 0b00001000) setb(PB1); else clrb(PB1); if(data & 0b00010000) setb(PB0); else clrb(PB0); if(data & 0b00100000) setd(PD7); else clrd(PD7); if(data & 0b01000000) setd(PD6); else clrd(PD6); Basicamente comparo o byte com uma mascara se o resultado for verdadeiro ele acendera o led que quero. Funcionou bem mas tive que fazer mudanças no hardware e no código para funcionar. Lembre aos que quiserem fazer projetos assim, faça a sua tabela alfanumérica coincidir com a disposição dos led em seu hardware facilita muito a vida.
  5. Infelizmente o minimalismo se faz necessário, pois a velocidade com que ele vai processar isso influencia na projeção da minha imagem. Vou continuar procurando uma solução que inverta o byte como já mencionado. Se encontrar posto aqui para futuras consultas.
  6. Infelizmente assim não vai dar, pois eu já tenho uma lista de vetores aonde cada célula do meu vetor é um byte, assim: const char A_seq[5] = {0x7e,0x09,0x09,0x09,0x7e}; Eu leio no meu código um byte por vez, assim PORTB = 0x7e; Assim consigo acender leds numa sequencia especifica, porém preciso inverter esse byte para acender a sequencia corretamente. A ideia é inverter ele em seguida deslocá-lo assim consigo por parte dele em um PORT e parte em OUTRO. Exemplo: Original - 0b01001110 Inverto - 0b01110010 data = 0b01110010; PORTB = data>>3; //0b00001110 PORTD = data<<5; //0b01000000 A ideia é essa.
  7. Boa noite, estou com a seguinte questão tenho um conjunto de bits e preciso inverte-los da seguinte maneira. Original - 0b01001111 Invertido - 0b11110010 A segunda questão é preciso deslocar esses bits depois de invertidos da seguinte maneira. Invertido - 0b11110010 Deslocado - 0b11001000 No deslocamento eu posso perder os bits deslocados não a problema. Se alguém saber aonde posso achar algo que me ajude a fazer isso eu ficaria muito agradecido.
  8. @Isadora Ferraz Então eu testei não deu muito certo, vou reescrever os bits pra ficar certo.
  9. Pessoal o que vocês sugeriram deu certo, porém surgiu um probleminha, eu preciso inverter os bytes que contem a informação dos leds que serão acessos da seguinte forma. 76543210 76543210 data = 0x00001001 ====>> data = 0x10010000 E ai alguma sugestão?
  10. Vou fazer o que vocês estão sugerindo mesmo. Parece que vau ficar melhor assim.
  11. Não estou confundindo, a pessoa que desenvolveu o código é um americano e ele fez para o PIC16F628. Nessa parte do código: rom char* A_seq = {0x7e,0x09,0x09,0x09,0x7e}; rom char* B_seq = {0x7f,0x49,0x49,0x49,0x3e}; rom char* C_seq = {0x3e,0x41,0x41,0x41,0x22}; rom char* D_seq = {0x7f,0x41,0x41,0x41,0x3e}; rom char* E_seq = {0x7f,0x49,0x49,0x49,0x41}; rom char* F_seq = {0x7f,0x09,0x09,0x09,0x01}; ... Ele grava uma tabela de caracteres na memoria EEPROM do microcontrolador durante a gravação do microcontrolador. Depois de gravado ele só recupera esses valores da EEPROM, gostaria de fazer o mesmo mas com o ATMEGA328P.
  12. Então @Isadora Ferraz ele utiliza o PORTA e PORTB, pois não tem pinos suficientes, no caso do ATMEGA328P daria pra usar o PORTB ou PORTC inteiro como você fez ali, pois ele possui pinos suficientes. O programa funciona perfeitamente para o PIC, mas é necessário mudar algumas coisas nele para funcionar no AVR, primeiro queria colocar aquela tabela com os caracteres na memoria EEPROM na gravação do microcontrolador da mesma maneira que ele fez e omo o ATMEGA tem mais memoria EEPROM eu vou colocar mais caracteres depois. Eu ainda não fiz o esquemático kkkk mas faço hj e posto mais tarde. kkk
  13. Bom dia a todos, estou querendo portar um código em C escrito para o microcontrolador PIC16F628 para um microcontrolador AVR ATMEGA328P. O código que quero portar é de um POV (display rotativo), como não tenho todo o conhecimento necessário pensei que alguém poderia me ajudar. Segue o código: #include <system.h> #include <eeprom.h> //Target PIC16F628 configuration word #pragma DATA _CONFIG, 0x3F18 //Set clock frequency #pragma CLOCK_FREQ 4000000 unsigned char message[60]; unsigned char data; unsigned char address; rom char* A_seq = {0x7e,0x09,0x09,0x09,0x7e}; rom char* B_seq = {0x7f,0x49,0x49,0x49,0x3e}; rom char* C_seq = {0x3e,0x41,0x41,0x41,0x22}; rom char* D_seq = {0x7f,0x41,0x41,0x41,0x3e}; rom char* E_seq = {0x7f,0x49,0x49,0x49,0x41}; rom char* F_seq = {0x7f,0x09,0x09,0x09,0x01}; rom char* G_seq = {0x3e,0x41,0x41,0x49,0x7a}; rom char* H_seq = {0x7f,0x08,0x08,0x08,0x7f}; rom char* I_seq = {0x00,0x41,0x7f,0x41,0x00}; rom char* J_seq = {0x20,0x40,0x41,0x3f,0x01}; rom char* K_seq = {0x7f,0x08,0x14,0x22,0x41}; rom char* L_seq = {0x7f,0x40,0x40,0x40,0x40}; rom char* M_seq = {0x7f,0x02,0x04,0x02,0x7f}; rom char* N_seq = {0x7f,0x02,0x04,0x08,0x7f}; rom char* O_seq = {0x3e,0x41,0x41,0x41,0x3e}; rom char* P_seq = {0x7f,0x09,0x09,0x09,0x06}; rom char* Q_seq = {0x3e,0x41,0x51,0x21,0x5e}; rom char* R_seq = {0x7f,0x09,0x19,0x29,0x46}; rom char* S_seq = {0x46,0x49,0x49,0x49,0x31}; rom char* T_seq = {0x01,0x01,0x7f,0x01,0x01}; rom char* U_seq = {0x3f,0x40,0x40,0x40,0x3f}; rom char* V_seq = {0x1f,0x20,0x40,0x20,0x1f}; rom char* W_seq = {0x3f,0x40,0x38,0x40,0x3f}; rom char* X_seq = {0x63,0x14,0x08,0x14,0x63}; rom char* Y_seq = {0x03,0x04,0x78,0x04,0x03}; rom char* Z_seq = {0x61,0x51,0x49,0x45,0x43}; rom char* a_seq = {0x30,0x4a,0x4a,0x4a,0x7c}; //a rom char* b_seq = {0x7f,0x50,0x48,0x48,0x30}; //b rom char* c_seq = {0x38,0x44,0x44,0x44,0x20}; //c rom char* d_seq = {0x38,0x44,0x44,0x48,0x7f}; //d rom char* e_seq = {0x38,0x54,0x54,0x54,0x18}; //e rom char* f_seq = {0x08,0x7e,0x09,0x01,0x02}; //f rom char* g_seq = {0x06,0x49,0x49,0x49,0x3f}; //g rom char* h_seq = {0x7f,0x08,0x04,0x04,0x78}; //h rom char* i_seq = {0x00,0x44,0x7d,0x40,0x00}; //i rom char* j_seq = {0x20,0x40,0x44,0x3d,0x00}; //j rom char* k_seq = {0x7f,0x10,0x28,0x44,0x00}; //k rom char* l_seq = {0x00,0x41,0x7f,0x40,0x00}; //l rom char* m_seq = {0x7c,0x04,0x08,0x04,0x78}; //m rom char* n_seq = {0x7c,0x08,0x04,0x04,0x78}; //n rom char* o_seq = {0x38,0x44,0x44,0x44,0x38}; //o rom char* p_seq = {0x7c,0x14,0x14,0x14,0x08}; //p rom char* q_seq = {0x08,0x14,0x14,0x18,0x7c}; //q rom char* r_seq = {0x7c,0x08,0x04,0x04,0x08}; //r rom char* s_seq = {0x48,0x54,0x54,0x54,0x20}; //s rom char* t_seq = {0x04,0x3f,0x44,0x40,0x20}; //t rom char* u_seq = {0x3c,0x40,0x40,0x20,0x7c}; //u rom char* v_seq = {0x1c,0x20,0x40,0x20,0x1c}; //v rom char* w_seq = {0x3c,0x40,0x30,0x40,0x3c}; //w rom char* x_seq = {0x44,0x28,0x10,0x28,0x44}; //x rom char* y_seq = {0x0c,0x50,0x50,0x50,0x3c}; //y rom char* z_seq = {0x44,0x64,0x54,0x4c,0x44}; //z rom char* n0_seq = {0x3e,0x51,0x49,0x45,0x3e}; rom char* n1_seq = {0x00,0x42,0x7f,0x40,0x00}; rom char* n2_seq = {0x42,0x61,0x51,0x49,0x46}; rom char* n3_seq = {0x22,0x41,0x49,0x49,0x36}; rom char* n4_seq = {0x18,0x14,0x12,0x7f,0x10}; rom char* n5_seq = {0x27,0x45,0x45,0x45,0x39}; rom char* n6_seq = {0x3e,0x49,0x49,0x49,0x30}; rom char* n7_seq = {0x01,0x71,0x09,0x05,0x03}; rom char* n8_seq = {0x36,0x49,0x49,0x49,0x36}; rom char* n9_seq = {0x06,0x49,0x49,0x29,0x1e}; rom char* exp_seq = { 0x00,0x0,0x5f,0x0,0x0}; rom char* colon_seq= { 0x00,0x36,0x36,0x0,0x0}; rom char* space_seq ={ 0,0,0,0,0 }; rom char* heart_seq = {0x0c,0x1e,0x3c,0x1e,0x0c}; rom char* asterisk_seq = {0x2a,0x1c,0x7f,0x1c,0x2a}; bit oldVal; int idx; rom char *GetByteList(char c) { switch(c) { case 1: return A_seq; case 2: return B_seq; case 3: return C_seq; case 4: return D_seq; case 5: return E_seq; case 6: return F_seq; case 7: return G_seq; case 8: return H_seq; case 9: return I_seq; case 10: return J_seq; case 11: return K_seq; case 12: return L_seq; case 13: return M_seq; case 14: return N_seq; case 15: return O_seq; case 16: return P_seq; case 17: return Q_seq; case 18: return R_seq; case 19: return S_seq; case 20: return T_seq; case 21: return U_seq; case 22: return V_seq; case 23: return W_seq; case 24: return X_seq; case 25: return Y_seq; case 26: return Z_seq; case 33: return a_seq; case 34: return b_seq; case 35: return c_seq; case 36: return d_seq; case 37: return e_seq; case 38: return f_seq; case 39: return g_seq; case 40: return h_seq; case 41: return i_seq; case 42: return j_seq; case 43: return k_seq; case 44: return l_seq; case 45: return m_seq; case 46: return n_seq; case 47: return o_seq; case 48: return p_seq; case 49: return q_seq; case 50: return r_seq; case 51: return s_seq; case 52: return t_seq; case 53: return u_seq; case 54: return v_seq; case 55: return w_seq; case 56: return x_seq; case 57: return y_seq; case 58: return z_seq; case 59: return n0_seq; case 60: return n1_seq; case 61: return n2_seq; case 62: return n3_seq; case 63: return n4_seq; case 64: return n5_seq; case 65: return n6_seq; case 66: return n7_seq; case 67: return n8_seq; case 68: return n9_seq; case 69: return exp_seq; case 70: return colon_seq; case 71: return heart_seq; case 72: return asterisk_seq; } // Everything else is a space return space_seq; }; void showData(const char data) { if(data & 0b0000001) clear_bit(portb,3); else set_bit(portb,3); if(data & 0b0000010) clear_bit(porta,7); else set_bit(porta,7); if(data & 0b0000100) clear_bit(porta,6); else set_bit(porta,6); if(data & 0b0001000) clear_bit(portb,7); else set_bit(portb,7); if(data & 0b0010000) clear_bit(portb,6); else set_bit(portb,6); if(data & 0b0100000) clear_bit(portb,5); else set_bit(portb,5); if(data & 0b1000000) clear_bit(portb,4); else set_bit(portb,4); } void showMessage(const char *message, char count) { char i; char j; char data; rom char *sequence; for(j=0; j<count; j++) { sequence = GetByteList(message[j]); for(i=0; i<5; i++) { // Display column data = sequence[i]; showData(data); delay_us(200); delay_us(200); // All Off portb = 0xff; porta = 0xff; delay_us(200); delay_us(200); } // Space between letters. delay_ms(1); } }; void programming() { unsigned char data = 1; unsigned char i,j; unsigned char count; for(i=0; i<3;i++) { for(j=0;j<7;j++) { showData(data); data <<= 1; data |= 1; delay_ms(45); } for(j=0;j<7;j++) { data >>= 1; showData(data); delay_ms(45); } } while(!portb.1 || !portb.2); // Wait for both buttons to be released data = eeprom_read(address); showData(data); while(1) { count = 10; while(!portb.1 && count) { delay_ms(2); count--; } if(count == 0) // Held down for 20ms? { data++; if(data>0x7f) data = 0; showData(data); count = 80; while(!portb.1) { delay_ms(15); if(count) count--; if(count==0) { data++; if(data>73) data=0; showData(data); if(data==0 || data==16 || data ==32 || data==48 || data==64) { while(!portb.1); } } } } if(!portb.2) // Button 2 is pressed { delay_ms(10); if(!portb.2) // Is it still pressed? { eeprom_write(address++,data); data = eeprom_read(address); showData(data); while(!portb.2); // Wait for release } } } } void main( void ) { cmcon = 7; //disable comparators clear_bit( option_reg, 7 ); //Configure port A trisa = 0x00; //Configure port B trisb = 0x07; // RB0, 1, 2 are inputs. //Initialize port A porta = 0x00; //Initialize port B portb = 0x00; delay_ms(100); address = 0; while((data = eeprom_read(address)) != 0) { message[address++] = data; } if(!portb.1 || !portb.2) { address = 0; programming(); } else { //Endless loop while( 1 ) { showMessage(message,address); //while(portb.0); //while(!portb.0); delay_ms(7); }; } } Acho que a primeira dificuldade é encontrar o equivalente que salva na memoria a sequencia de bytes para cada letra do alfabeto. Já que esta não funciona para o AVR. rom char* A_seq = {0x7e,0x09,0x09,0x09,0x7e};
  14. A função if a seguir: if(data & 0b0000001) clear_bit(portb,3); else set_bit(portb,3); Na condição (data & 0b0000001) ela verdadeira quando data é igual ao byte 0b0000001?
  15. O código abaixo é uma mutretagem que não esta funcionando muito bem, nele uso a função "sprintf", mas pra converter int em string. void status(float temp, int dog, float pot) // Atualiza com o status de temperatura e potência { /*int temp2 = temp*100; int pot2 = pot*100; USART_Transmit(0x23); USART_Transmit(0x43); sprintf(atualiza_status,"%d",temp2); USART_putstring(atualiza_status);*/ int temp2 = (int)temp; int temp3 = (temp-temp2)*100; int pot2 = (int)pot; int pot3 = (pot-pot2)*100; USART_Transmit(0x23); USART_Transmit(0x43); if(temp2<10) { if (temp2 == 0) { USART_putstring("00"); } else { USART_Transmit(0x30); sprintf(atualiza_status,"%d",temp2); USART_putstring(atualiza_status); } } else { sprintf(atualiza_status,"%d",temp2); USART_putstring(atualiza_status); } if(temp3<10) { if (temp3 == 0) { USART_putstring("00"); } else { USART_Transmit(0x30); sprintf(atualiza_status,"%d",temp3); USART_putstring(atualiza_status); } } else { sprintf(atualiza_status,"%d",temp3); USART_putstring(atualiza_status); } USART_Transmit(0x44); sprintf(dog_pres,"%d",dog); USART_putstring(dog_pres); /*USART_Transmit(0x57); sprintf(atualiza_status,"%d",pot2); USART_putstring(atualiza_status);*/ USART_Transmit(0x57); if(pot2<10) { if (pot2 == 0) { USART_putstring("00"); } else { USART_Transmit(0x30); sprintf(atualiza_status,"%d",pot2); USART_putstring(atualiza_status); } } else { sprintf(atualiza_status,"%d",pot2); USART_putstring(atualiza_status); } if(pot3<10) { if (pot3 == 0) { USART_putstring("00"); } else { USART_Transmit(0x30); sprintf(atualiza_status,"%d",pot3); USART_putstring(atualiza_status); } } else { sprintf(atualiza_status,"%d",pot3); USART_putstring(atualiza_status); } USART_Transmit(0x2A); } Basicamente como não consegui converter de float para string eu converti para um numero inteiro com 4 algarismos sendo os dois ultimo os decimais do meu float.
  16. Na verdade quero converter de float para string, no site http://www.cplusplus.com a função indicada é a sprintf, mas ela não imprime nada só converte.
  17. Estou tentando converter uma variável float em string usando a biblioteca "stdio.h" e a função "sprintf", porém não esta convertendo a variável float. Utilizo a função desta maneira: sprintf(atualiza_status, "%.2f", temp); Onde, atualiza_status é um char de 10 posições. Sempre que uso este codigo e print algo depois de converte aparece isso: #C?*, onde o "?" deveria ser o numero da minha variável float. O microcontrolador que estou usando é o ATMEGA328P.
  18. Consegui fazer funcionar mas a solução que dei foi a seguinte, no NodeMCU eu inicializo a USART depois de ter conectado no wifi, assim evitando na inicialização aquelas mensagem estranhas, porém se cair a conexão ao se reconectar ele ainda envia essas mensagens estranhas e esse bug da mesmo com eu colocando no protocolo de comunicação um inicio e fim de mensagem, como exemplo "#Sxxxx*" onde "#" é o inicio e o "*" é o fim da mensagem. É uma coisa estranha o que acontece.
  19. Então consegui resolver em parte o problema de comunicação, porém na inicialização do NodeMCU a um problema, ele envia uma string com vários caracteres e essa string bagunça parte minha comunicação serial onde o ATMEGA para de receber os dados enviados no NodeMCU, acredito que fazendo que essa string não seja enviado resolva o problema, o problema é como. Se alguém saber uma maneira de não ser enviado essa string usando o Blynk. agradeço.
  20. @Bommu Perneta Então ontem continuei os teste com os dois equipamento e percebi que esse problema quando envio mais do que um byte para o meu ATMEGA, quando envio um byte do NodeMCU para o ATMEGA ele recebe de boa e faz a ação, porém quando envio uma string ele não funciona, o mais engraçado é que quando envio a mesma string pelo computador ela funciona no ATMEGA na boa. Meu problema pode estar no envio pelo TX do NodeMCU ou no recebimento pelo RX do ATMEGA. Alguém da uma forcinha que esse problema ta tenso.
  21. Boa noite, estou tentando fazer uma comunicação serial entre um NodeMCU e um ATMEGA328P, a principio a comunicação serial que criei funciona muito bem entre o PC-NodeMCU e entre o PC-ATMEGA, porém quando tento fazer a comunicação entre NodeMCU-ATMEGA as coisas funcionam parcialmente, o que ocorre é que a string enviada do ATMEGA para o NodeMCU e recebida numa boa e tratada e os dados são printados no APP BLYNK. porém quando tento enviar um comando através de uma string do NodeMCU para o ATMEGA este não executa corretamente. Descrição do que ocorre, eu envio um comando através do BLYNC para o NodeMCU este por sua vez envia uma string pela serial com a mensagem "#P1*" para ATMEGA nele o led do rx pisca porém não executa o meu comando. Tem duas possibilidades aonde o erro pode estar sendo estas no envio pelo NodeMCU ou no recebimento pelo ATMEGA. Abaixo o código para o ATMEGA e para o NodeMCU respectivamente. ATMEGA #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <avr/interrupt.h> #define FOSC 16000000 // Clock Speed #define BAUD 1200 #define MYUBRR FOSC/16/BAUD-1 // Variaveis do ADC float Tc = 11.55; // Variavél que armazena a temperatura convertida para Celsus int pont = 0; int frame_ok = 0; char ch[10] = "\0"; char atualiza_status[10] = "\0"; int Tempo = 16666; volatile char msbyte = 0; // Variavél que armazena os bits mais significativos volatile char lsbyte = 0; // variavél que armazena os bits menos significativos volatile int cont = 120; void config_uC() { DDRB |= (1<<PB5)|(1<<PB0); PORTB &= ~(1<<PB5); PORTB &= ~(1<<PB0); } void config_interrupt_timer(){ cli(); // Desabilita todas as interrupções para configuração TCCR1A = 0x00; TCCR1B = (1<<WGM12)|(1<<CS11); // Modo de operação: CTC; preescaler de 1:8 OCR1A = 0; // Inicia o timer em valor diferente de zero TIMSK1 |= (1<<OCIE1A); // Habilita interrupção pelo timer1 sei(); // Reabilita todas as interrupções } void USART_Init( unsigned int ubrr) { /*Set baud rate */ UBRR0H = (unsigned char)(ubrr>>8); UBRR0L = (unsigned char)ubrr; /*Enable receiver and transmitter */ UCSR0B = (1<<RXEN0)|(1<<TXEN0); /* Set frame format: 8data, 1stop bit */ UCSR0C = (3<<UCSZ00); } void USART_Transmit( unsigned char data ) { /* Wait for empty transmit buffer */ while (!( UCSR0A & (1<<UDRE0))); /* Put data into buffer, sends the data */ UDR0 = data; } unsigned char USART_Receive( void ) { /* Wait for data to be received */ while (!(UCSR0A & (1<<RXC0))); /* Get and return received data from buffer */ return UDR0; } void USART_putstring(char* StringPtr) { while (*StringPtr != 0x00) { USART_Transmit(*StringPtr); StringPtr++; } } void USART_getstring() { if((UCSR0A & (1<<RXC0))) { ch[pont] = UDR0; if (ch[0] != 0x23) { pont = 0; } if((ch[pont] == 0x2A) && (ch[0] == 0x23)) { frame_ok = 1; pont = 0; } else { pont++; } } } void on_off() { if(ch[2] == 0x31) { //USART_putstring("ON"); PORTB |= (1<<PB5); } else { //USART_putstring("OFF"); PORTB &= ~(1<<PB5); } } void status(float temp) { USART_Transmit(0x23); USART_Transmit(0x43); int temp2 = temp*100; sprintf(atualiza_status,"%d",temp2); USART_putstring(atualiza_status); USART_Transmit(0x2A); } void led_pisca() { PORTB |= (1<<PB0); _delay_ms(100); PORTB &= ~(1<<PB0); _delay_ms(100); } void comando() { if (frame_ok) { switch(ch[1]) { case 'P': on_off(); led_pisca(); break; } frame_ok = 0; memset(ch, '\0', sizeof(ch)); } } ISR(TIMER1_COMPA_vect) // Função da Interrupção pelo Timer0 { USART_getstring(); cont--; } int main(void) { config_uC(); config_interrupt_timer(); USART_Init(MYUBRR); msbyte = (Tempo & 0xFF00) >> 8; lsbyte = Tempo; OCR1AH = msbyte; OCR1AL = lsbyte; while (1) { comando(); Tc = Tc + 1.0; status(Tc); while(cont != 0); cont = 120; } } NodeMCU #define BLYNK_PRINT Serial #include <string.h> #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "e8093a41d5a94af3b7dfb954998bbf31"; // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "Copel71"; char pass[] = "36927100"; int pont = 0; int frame_ok = 0; char chr[14] = "\0"; float Temp = 0.0; BLYNK_WRITE(V0) { int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable if(pinValue) { Serial.print("#P1*"); } else { Serial.print("#P0*"); } } BLYNK_READ(V3) { // This command writes Arduino's uptime in seconds to Virtual Pin (5) Blynk.virtualWrite(V3, Temp); } void USART_getstring() { if(Serial.available()>0) { int ch = Serial.read(); chr[pont] = ch; if(chr[0] != 0x23) { pont = 0; } if((chr[pont] == 0x2A) && (chr[0] == 0x23)) { pont = 0; frame_ok = 1; } else { pont++; } } } void setup() { Serial.begin(1200); Blynk.begin(auth, ssid, pass); } void loop() { Blynk.run(); USART_getstring(); if(frame_ok) { Temp = ((chr[2]-0x30)*1000+(chr[3]-0x30)*100+(chr[4]-0x30)*10+(chr[5]-0x30))/100.0; frame_ok = 0; } } Se alguém poder me ajudar.
  22. Boa noite amigos, estou com o um problema que ainda não descobri como resolver. O problema é este, tenho uma string (texto qualquer max. 10 caracteres alfanuméricos) e quero enviar via USART para um atmega328 programado em C para AVR e armazenar em um buffer essa string. Segue o codigo: #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #include <string.h> #include <stdio.h> #define FOSC 16000000 // Clock Speed #define BAUD 9600 #define MYUBRR FOSC/16/BAUD-1 int cont = 0; void USART_Init( unsigned int ubrr) { /*Set baud rate */ UBRR0H = (unsigned char)(ubrr>>8); UBRR0L = (unsigned char)ubrr; /*Enable receiver and transmitter */ UCSR0B = (1<<RXEN0)|(1<<TXEN0); /* Set frame format: 8data, 1stop bit */ UCSR0C = (3<<UCSZ00); } void USART_Transmit( unsigned char data ) { /* Wait for empty transmit buffer */ while (!( UCSR0A & (1<<UDRE0))); /* Put data into buffer, sends the data */ UDR0 = data; } void USART_putstring(char* StringPtr) { while (*StringPtr != 0x00) { USART_Transmit(*StringPtr); StringPtr++; } } unsigned char USART_Receive( void ) { /* Wait for data to be received */ while (!(UCSR0A & (1<<RXC0))); /* Get and return received data from buffer */ return UDR0; } void config_uC(){ DDRB |= (1<<PB5); PORTB &= ~(1<<PB5); } int main(void) { config_uC(); USART_Init(MYUBRR); while (1) { USART_putstring("Ola Mundo!!!"); USART_Transmit(0x3B); char buffer[10]; sprintf(buffer,"%i",cont); USART_putstring(buffer); USART_Transmit(0x3B); //sprintf(buffer2,"%c",USART_Receive()); //USART_putstring(buffer2); USART_Transmit(0x0A); USART_Transmit(0x0D); PORTB ^= (1<<PB5); _delay_ms(1000); cont++; } } Todas as funções implementadas funcionam, porém a USART_receive() recebe apenas um BYTE por execução da função. O que quero é armazenar esse BYTE em um "char buffer2[10]", para depois tratar a informação. Alguém sabe como fazer isso ou o caminho para conseguir.
  23. Boa noite pessoal, um tópico rápido aqui, estou procurando alguma biblioteca para implementar comunicação serial USART utilizando o atmega328 e programando em avr. Alguém conhece alguma biblioteca que possua as principais funções de configuração, enviar e receber???
  24. Boa noite amigos, então ontem de noite consegui fazer funcionar da maneira que eu queria o projeto, vou deixar o código logo a baixo pra futuras referencias. Mas o que ocorreu foi o seguinte, eu estava errando em habilitar e desabilitar a interrupção por timer para conseguir controlar o tempo de disparo desta interrupção. O que eu deveria ter feito desde o inicio era dar um stop logo após entrar na interrupção do timer e um start logo após entrar na interrupção externa. Mas depois que descobri isso fiquei quebrando a cabeça para encontrar os bit responsável por isso, e para minha surpresa no datasheet do atmega328 não consta nada disso detalhado em texto, apenas encontramos essa informação em uma unica linha da tabela do registrador TCCR1B e os bits responsáveis por esse start e stop são os CS2:0. E como funciona isso, é simples quando você quer dar um stop no timer1 você deixar todos os bits CS2:0 em zero, e quando você quer reiniciar a contagem você seta o preescaler que deseja. Fácil néeeee e para encontrar esse macete, tremenda sacagem kkkkkkk, segue a tabela aonde encontrei a informação. Agora segue um código que fiz para testar isso. #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define F_CPU 16000000UL int Tempo = 1000; volatile char msbyte = 0; volatile char lsbyte = 0; void config_uC(){ //Configuração das portas do uC DDRC |= (1<<PC0)|(1<<PC1); PORTC = 0x00; DDRD |= (1<<PD2); PORTD &= ~(1<<PD2); } void config_interrupt(){ //Configuração da interrupção externa PD3/INT0 cli(); EICRA |= (1<<ISC10)|(1<<ISC11); EIMSK |= (1<<INT1); sei(); } void config_interrupt_timer(){ cli(); TCCR1A = 0x00; TCCR1B = (1<<WGM12)|(1<<CS11); OCR1A = 8000; TIMSK1 |= (1<<OCIE1A); sei(); } ISR(INT1_vect){ PORTC ^= (1<<PC0); OCR1AH = msbyte; //Transfere os bits mais significativos do tempo calculado OCR1AL = lsbyte; //Transfere os bits menos significativos do tempo calculado PORTD &= ~(1<<PD2); PORTC &= ~(1<<PC1); TCCR1B |= (1<<CS11); //START } ISR(TIMER1_COMPA_vect){ TCCR1B &= ~(1<<CS11); //STOP PORTD |= (1<<PD2); PORTC |= (1<<PC1); } int main(void){ config_uC(); config_interrupt(); config_interrupt_timer(); while(1){ msbyte = (Tempo & 0xFF00) >> 8; //Separa dos bits mais significativos do tempo lsbyte = Tempo; //Separa dos bits menos significativos do tempo Tempo = Tempo + 1000; if(Tempo > 16000) Tempo = 1000; _delay_ms(5000); } } Esse programa sincroniza com a rede elétrica e faz os disparar a interrupção do timer dentro do período entre uma interrupção externa e outra, alterando o tempo de disparo a cada 5 segundos, incrementando 500us até chegar a 8ms. Depois reinicia o ciclo. Queria agradecer a todos e me ajudaram neste problema. Att Thiago.
  25. Então amigos voltei, desculpe a demora mais estava testando varias coisas aqui, e acho que encontrei o problema, só não sei a causa e como resolve-ló. Então primeiro o código e depois explicações do ocorrido. #include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 16000000UL void config_uC(){ DDRC |= (1<<PC0)|(1<<PC1); PORTC = 0x00; } void config_interrupt(){ cli(); EICRA |= (1<<ISC10); EICRA |= (1<<ISC11); EIMSK |= (1<<INT1); sei(); } void config_interrupt_timer1(){ cli(); TCCR1A = 0x00; TCCR1B |= (1<<WGM12)|(1<<CS11); //habilita o modo CTC, configura o preescaler 8 OCR1A = 8000; //temporização de 4ms TIMSK1 &= ~(1<<OCIE1A); //desabilitada a interrupção por timer sei(); } ISR(INT1_vect){ PORTC ^= (1<<PC0); //troca o estado do pino PC0 a cada interrupção externa PORTC &= ~(1<<PC1); //reseta o pino PC1 do timer OCR1A = 8000; //temporização de 4ms TIMSK1 |= (1<<OCIE1A); //habilitada a interrupção por timer } ISR(TIMER1_COMPA_vect){ PORTC |= (1<<PC1); //seta o pino PC1 do timer / indica a entrada na rotina de interrupção do timer TIMSK1 &= ~(1<<OCIE1A); //desabilita a interrupção por timer } int main(void) { config_uC(); config_interrupt(); config_interrupt_timer1(); while(1); } Aqui esta o código bem simples e limpo, no meu main() só tem as rotinas de configuração das portas do uC, da interrupção externa e do timer e o loop infinito. Na configuração da interrupção externa eu configurei ela para interromper sempre que aparecer uma borna de subida. Na configuração da interrupção do timer eu configurei o modo CTC, que interrompe sempre que meu contador chegar no OCR1A ocorrendo assim o estouro do timer, a temporização configurada é de 4ms, eu testei essa configuração utilizando somente o timer e nada mais, trocando o estado de um pino a cada 4ms e no osciloscópio apareceu bonitinho a forma de onda que eu queria. O que esse código deveria fazer é simples, sempre que ocorrer uma interrupção externa que nesse caso ocorre num período de exatos 8,3ms (verificado no osciloscópio) ele troca o estado do pino PC0, abaixa o pino PC1, seta o registrador OCR1A e por habilita a interrupção do timer. Por sua vez, o timer habilitado temporiza 4ms, até ocorrer seu estouro e assim entrar na rotina de interrupção ativando o pino PC1, em seguida desabilita a interrupção do timer. A seguir uma figura dos estados dos pinos como deveria funcionar: O pino PC0 é referente a interrupção externa, e o pino PC1 e referente a interrupção do timer. A forma de onda que deveria ser visualizada no osciloscópio deveria ser esta acima. O que realmente acontece segue nas imagens abaixo tiradas do osciloscópio. Nesta imagem, podemos ver em azul a forma de onda da interrupção externa que troca o estado do pino PC0 a cada 8,3ms (isso esta funcionando direito). Em amarelo podemos ver a forma de onda da interrupção pelo timer. Aqui já notamos um problema ele não esta temporizando os 4ms que especifiquei. Aqui temos um zoom nas formas de onda focalizando bem o inicio da interrupção externa, podemos verificar na curva em amarelo que a interrupção do timer esta sendo habilitada a cada cilclo e que conseguimos entrar dentro da rotina da interrupção do timer a prova disso é que o pino PC1 é elevado ao nível alto, porém o que não ocorre é a temporização dos 4ms. E depois de toda essa explicação, testes, figuras e tudo mais, chego a conclusão que a unica coisa que não esta funcionando é essa temporização eu realmente estou quebrando a cabeça pra saber o porque, suspeito que seja algum registrador não configurado, mas mesmo assim esta muito estranho pois configurando só o timer eu consigo os exatos 4ms. Vou continuar a trabalhar nisso espero que com isso possamos resolver esse problema para que ninguém mais caia nessa mesma armadilha.

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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!