Ir ao conteúdo
  • Cadastre-se

_FBO_

Membro Júnior
  • Posts

    4
  • Cadastrado em

  • Última visita

Reputação

4
  1. Muito interessante, é uma nova maneira em que eu não havia pensado. Vou fazer desta maneira. E muito obrigado pelas considerações que me ajudam a melhorar cada vez mais. Abraço
  2. Certo vou tentar explicar melhor o que estou tentando fazer: ter um código generico, que eu possa reutilizar em varios programas, pra fazer interface de acesso a leitura/edição de variaveis. Pra isso eu gero vetores de uma estrutura para categorizar um grupo de variaveis. Vou apresentar um exemplo: um sistema que faz o controle de uma impressora 3D. Este sistema possui parametros de ajustes genericos como velocidade de execução, temperatura da mesa e da extrusora e parametros de cada motor. Para categorizar esses parametros utilizando meu codigo seria algo como: typedef struct{ char *descricao; void *variavel; char tipo; }params_t; //tela de parametros genericos (veja obsevacao ao termino da definição do vetor "Params0") params_t Params0[]={ {"Tempo restante (seg)", &tempo_restante, FLOAT}, {"Velocidade de execucao (mm/min)", &feed_rate, FLOAT}, {"Temperatura da mesa (graus)", &temper_mesa, FLOAT}, {"Temperatura da extrusora (graus)", &temper_extrusora, FLOAT}, {NULL,NULL,NULL} }; //osb: o campo "Tempo restante (seg)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params0" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina. //parametros do eixo X params_t Params1[]{ {"Posicao atual (mm)", &medida_x, FLOAT}, {"Ajuste de medida", &steps_per_mm_x, FLOAT}, {"Velocidade maxima (mm/min)", &max_speed_x, UINT}, {"Limite eletrônico (mm)", &lim_x, UINT}, {NULL,NULL,NULL} }; //osb: o campo "Posicao atual (mm)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params1" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina. //parametros do eixo Y params_t Params2[]{ {"Posicao atual (mm)", &medida_y, FLOAT}, {"Ajuste de medida", &steps_per_mm_y, FLOAT}, {"Velocidade maxima (mm/min)", &max_speed_y, UINT}, {"Limite eletrônico (mm)", &lim_y, UINT}, {NULL,NULL,NULL} }; //osb: o campo "Posicao atual (mm)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params2" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina. Veja que tenho campos utilizados para leitura, que podem ser atualizados a qualquer momento em outros trechos do programa, que devem ser apresentados constantemente para o usuario e tenho também campos que somente são alterados por entrada de valor do usuário, não necessitando ser apresentado constantemente. Com isso eu daria um refresh na apresentação de todo o conteudo do vetor em uso apenas quando o usuario selecionar qual o vetor quer colocar em uso e daria refresh constantemente apenas do conteúdo que foi alterado. Aí que entra o "truque" que quero implementar: ter um espelho do vetor em uso para que eu possa comparar e ver quais os campos que foram alterados para fazer o refresh seletivo, a fim de poupar tempo de execução. Seria algo como essa sequencia: 1. espera usuario selecionar um vetor de parametros para visualizar/editar 2. apresenta o conteúdo do vetor selecionado (seja num display, via comunicação serial, etc) 3. carrega o conteúdo do vetor selecionado para um vetor espelho (alocação dinâmica) 4. monitora quais valores do vetor selecionado apresentam diferença em relação aos valores do vetor espelho (faz um "for" comparando os valores do vetor selecionado com o vetor espelho). 5. atualiza para o usuario os campos que sofreram alteração, seja num display, via comunicação serial, etc) 6. carrega o valor do campo alterado no vetor selecionado para o valor correspondente no vetor espelho para novas comparações durante o monitoramento 7. repete passos 4 a 6 enquanto o usuario não selecionar outro vetor diferente. Note que o conteúdo dos vetores de parametros podem ter campos com diferentes informações de texto, diferentes variaveis relacionadas e de diferentes tipos. Com este código posso facilmente acrescentar/remover novos parametros e assim reutilizar este código em outras aplicações que seguem o mesmo modelo de categorias de parametros
  3. Agradeço as considerações. Realmente faltou eu explicar algo: este aplicativo que apresentei foi com o intuito de exemplificar o problema que tenho em um programa embarcado. Então eu extraí trechos do código e montei este aplicativo de exemplo para que possam visualizar o problema principal: ter um espelho do conteúdo do vetor da estrutura apontada pela variável "item". E no vetor pode ter variaveis que em outro trecho do programa terão seu valor alterado por leitura de periféricos como sensores. O objetivo final é utilizar as estruturas como a interface central, onde posso apenas acrescentar uma nova linha referenciando uma variavel que poderá ser utilizada para apresentar ao usuario a leitura de algum sensor ou permitir que o usuario altere o valor de variaveis. Porém, por ser um sistema embarcado, não quero ficar reapresentando toda a tabela para o usuario se não houver atualização, posso enviar apenas as variaveis que tiveram seus valores modificados, seja por propria entrada do usuario ou seja por atualização proveniente de outras partes do programa. Com isso planejo economizar tempo de processamento do sistema. Eu não quero tambem consumir memória desnecessaria fazendo um espelho de todos os vetores de "estrutura_t" que posso ter. Neste exemplo eu apresentei apenas 2 vetores instanciados em "item_tab", mas posso ter vários vetores, cada um contendo várias entradas do tipo "estrutura_t". Por isso que, ao pegar o ponteiro de um vetor (variavel "item"), quero criar um espelho neste momento apenas do vetor apontado por "item", liberando da memória o espelho anterior antes de alocar um novo espelho
  4. Olá. Estou com dificuldade num código e preciso de ajuda... Tenho vetores de structs e um ponteiro para o vetor que está em uso (variavel "item" no codigo abaixo). Estou com essas dificuldades: 1. contar quantos itens tem em cada estrutura (veja variavel "qtd_items" no codigo abaixo) 2. como gerar um vetor clone (veja variavel "mirror" no codigo abaixo) que serve para monitorar alterações nas variaveis do vetor de "estrutura_t". Talvez pense: "mas dá pra saber quando o usuario faz alguma alteração de valores no código então não precisa ter um clone dos valores pra isso". Mas na verdade essas alterações não vão se limitar a operações de usuario, podem vir por causas externas (imagine que uma variavel apontada em uma das estruturas seja uma variavel de leitura de um sinal de sensor ou um contador de eventos de interrupção do sistema, então não dá pra saber quando houve alteração então por isso preciso de um clone da estrutura em uso para monitorar quando houver alterações pra poder salvar). 3. melhorias para a estrutura "item_t" também são bem-vindas, não sei se preciso dela para indicar qual vetor de "estrutura_t" está em uso, tentei de outra maneira mas não consegui compilar... Muito obrigado #include <stdio.h> #include <stdlib.h> #include <math.h> //definicoes #define UINT 0 #define ULONG 1 #define FLOAT 3 //declaracao de estruturas typedef struct{ char *descricao; void *variavel; char tipo; }estrutura_t; typedef struct{ estrutura_t *estrutura; char dummy; }item_t; union FloatBytes{ float f; unsigned char bytes[4]; }; //declaracao de variaveis unsigned int uint1,uint2,uint3; unsigned long ulong1,ulong2,ulong3; float float1,float2,float3; item_t *item; //ponteiro que indica a estrutura em uso item_t *mirror; //variavel que contem uma copia da estrutura em uso int qtd_items,current_index; //declaracao e inicializacao de vetores estrutura_t estrutura0[4]= { {"primeiro item", &uint1, UINT}, {"segundo item", &uint2, UINT}, {"terceito item", &float1, FLOAT}, {NULL,NULL,NULL} }; estrutura_t estrutura1[6]= { {"descricao da linha 1", &ulong1, ULONG}, {"conteudo da linha 2", &float2, FLOAT}, {"qualquer conteudo aqui", &uint3, UINT}, {"texto informativo", &ulong2, ULONG}, {"quinta linha", &uint3, UINT}, {NULL,NULL,NULL} }; item_t item_tab[2]={ {estrutura0,0}, {estrutura1,0}, }; void load_values(void) { int i,j; FILE *fp; char filename[10]; unsigned char buffer[4]; for(i=0; i<2; i++) { item= &item_tab[i]; //descobre quantos itens tem no vetor de estrutura apontado por "item" //aqui eu precisava de um jeito melhor de descobrir a quantidade de itens qtd_items=0; for(j=0; j<100; j++) { if(item->estrutura[j].descricao != NULL) qtd_items++; else break; } //agora carrega o arquivo que contem os valores das estruturas sprintf(filename,"file_%d.bin", i); fp= fopen(filename, "rb"); if(fp != NULL) { for(j=0; j<qtd_items; j++) { if(item->estrutura[j].tipo == UINT) { unsigned int temp_word; fread(buffer,2,1,fp); temp_word= buffer[0] << 8 | buffer[1]; *(unsigned int*)item->estrutura[j].variavel= temp_word; } else if(item->estrutura[j].tipo == ULONG) { unsigned long temp_long; fread(buffer,4,1,fp); temp_long= buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; *(unsigned long*)item->estrutura[j].variavel= temp_long; } else if(item->estrutura[j].tipo == FLOAT) { union FloatBytes fb; fread(fb.bytes,4,1,fp); *(float*)item->estrutura[j].variavel= fb.f; } } fclose(fp); } } } void printa(void) //printa a estrutura em uso { int i; for(i=0; i<qtd_items; i++) { if(item->estrutura[i].tipo == UINT) printf("\r\n[%d] %s= %u", i, item->estrutura[i].descricao, *(unsigned int*)item->estrutura[i].variavel); else if(item->estrutura[i].tipo == ULONG) printf("\r\n[%d] %s= %lu", i, item->estrutura[i].descricao, *(unsigned long*)item->estrutura[i].variavel); else if(item->estrutura[i].tipo == FLOAT) printf("\r\n[%d] %s= %f", i, item->estrutura[i].descricao, *(float*)item->estrutura[i].variavel); } } void gerencia_alteracoes(void) { int number; do{ printf("\r\nDeseja alterar qual variavel? (Insira -1 para cancelar): "); scanf("%d", &number); if(number == -1) return; }while(number < 0 || number > qtd_items); if(item->estrutura[number].tipo == UINT) { printf("\r\n[%d] %s= %u", number, item->estrutura[number].descricao, *(unsigned int*)item->estrutura[number].variavel); printf("\r\nInsira o novo valor: "); scanf("%u",(unsigned int*)item->estrutura[number].variavel); } else if(item->estrutura[number].tipo == ULONG) { printf("\r\n[%d] %s= %lu", number, item->estrutura[number].descricao, *(unsigned long*)item->estrutura[number].variavel); printf("\r\nInsira o novo valor: "); scanf("%lu",(unsigned long*)item->estrutura[number].variavel); } else if(item->estrutura[number].tipo == FLOAT) { printf("\r\n[%d] %s= %f", number, item->estrutura[number].descricao, *(float*)item->estrutura[number].variavel); printf("\r\nInsira o novo valor: "); scanf("%f",(float*)item->estrutura[number].variavel); } } void salva_alteracoes(void) { int i; char changed= 0; for(i=0; i<qtd_items; i++) { if(item->estrutura[i].tipo == UINT) { unsigned int ui1= *(unsigned int*)item->estrutura[i].variavel; unsigned int ui2= *(unsigned int*)mirror->estrutura[i].variavel; if(ui1 != ui2) { *(unsigned int*)mirror->estrutura[i].variavel= ui1; changed= 1; break; } } else if(item->estrutura[i].tipo == ULONG) { unsigned long ul1= *(unsigned long*)item->estrutura[i].variavel; unsigned long ul2= *(unsigned long*)mirror->estrutura[i].variavel; if(ul1 != ul2) { *(unsigned long*)mirror->estrutura[i].variavel= ul1; changed= 1; break; } } else if(item->estrutura[i].tipo == FLOAT) { float f1= *(float*)item->estrutura[i].variavel; float f2= *(float*)mirror->estrutura[i].variavel; if(fabs(f1 - f2) < 0.001) { *(float*)mirror->estrutura[i].variavel= f1; changed= 1; break; } } } if(changed) { FILE *fp; char filename[10]; unsigned char buffer[4]; sprintf(filename, "file_%d.bin", current_index); fp= fopen(filename,"wb"); for(i=0; i<qtd_items; i++) { if(item->estrutura[i].tipo == UINT) { buffer[0]= *(unsigned int*)item->estrutura[i].variavel >> 8; buffer[1]= *(unsigned int*)item->estrutura[i].variavel & 0xFF; fwrite(buffer,1,2,fp); } else if(item->estrutura[i].tipo == ULONG) { buffer[0]= *(unsigned long*)item->estrutura[i].variavel >> 24; buffer[1]= *(unsigned long*)item->estrutura[i].variavel >> 16; buffer[2]= *(unsigned long*)item->estrutura[i].variavel >> 8; buffer[3]= *(unsigned long*)item->estrutura[i].variavel & 0xFF; fwrite(buffer,1,4,fp); } else if(item->estrutura[i].tipo == FLOAT) { union FloatBytes fb; fb.f= *(float*)item->estrutura[i].variavel; fwrite(fb.bytes,1,4,fp); } } fclose(fp); } } void main(void) { int i; //carrega dados armazenados em arquivo para os vetores de "estrutura_t" load_values(); while(1) { //permite selecionar uma estrutura para visualizar/alterar do{ printf("\r\nQual menu deseja visualizar (0 ou 1)? Insira -1 para sair: "); scanf("%d", &current_index); if(current_index == -1) { free(mirror); return; } }while(current_index < 0 || current_index > 1); //usuario selecionou uma estrutura, carrega-a item= &item_tab[current_index]; qtd_items= 0; for(i=0; i<100; i++) { if(item->estrutura[i].descricao != NULL) qtd_items++; else break; } //aqui preciso criar a copia mas não sei como pois o conteudo é variavel free(mirror); mirror= (item_t*)malloc(sizeof(???)); memcpy(mirror,item,sizeof(???)); //apresenta o conteudo da estrutura em uso printa(); //permite alterar o valor das variaveis da estrutura em uso gerencia_alteracoes(); //compara se houver alteração em relação ao mirror e salva salva_alteracoes(); } }

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!