Página 1 de 3

Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 13:01
por lucasromeiro
Galera, tenho a necessidade de comprimir os dados que enviarei via gprs para consumir menos trafego de dados!!
preciso de ajuda, sei que é possivel mas nao estou entendendo como funciona.
Postei no forum da ccs, tive algumas respostas, mas devido o idioma e inexperiencia, nao compreendi muito bem.
alguem pode me ajudar?
aqui meu topico: http://www.ccsinfo.com/forum/viewtopic.php?t=54239

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 13:31
por xultz
Eu li a bagaça meio por cima (o thread é bem longo), mas o que o fulano sugeriu é converter tuas informações de ASCII para valor numérico, você entendeu esta parte? Seria bacana colocar de novo como é o formato dos dados que pretende transmitir, fica mais fácil ajudar desta forma.

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 14:41
por lucasromeiro
xultz escreveu:Eu li a bagaça meio por cima (o thread é bem longo), mas o que o fulano sugeriu é converter tuas informações de ASCII para valor numérico, você entendeu esta parte? Seria bacana colocar de novo como é o formato dos dados que pretende transmitir, fica mais fácil ajudar desta forma.


pois é, nao entendi muito bem, porque primeiro eles falam de transformar em hex ou binario.
blz transformou em hex e ai?
como seria em binario?
olha a ultima postagem da pagina 2.

Formato:

@9999;100;25/10/2015-23:22:34;int32;int32;int32;int32;int32;int32;int32;int8;
@(NumberOfClientMax);(signalMax);(time stamp); inteiros aleatorios

exemplo real de um pacote:
@0999;100;25/10/15-23:22:34;4294967290;500;0;15555;72;4294967290;9;50;

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 14:49
por andre_luis
Já procurou por funções prontas em C com o critério de busca "string data compression" ?
O código de Huffman parece ser o mais apropriado para pouca quantidade de dados.

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 15:10
por lucasromeiro
andre_teprom escreveu:Já procurou por funções prontas em C com o critério de busca "string data compression" ?
O código de Huffman parece ser o mais apropriado para pouca quantidade de dados.


ja sim amigo...
porem estes codigos sao usados economizando os caracteres repetidos em sequencia, coisa que nao existe no meu caso, olhe o formato dos meus dados, predominantemente numeros e mudam a cada dado.
nao ahei uma funcao pronta para tal. =(

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 15:55
por tcpipchip
Não podes fazer uma bridge com linux e usar o gzip ?

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 16:04
por andre_luis
Teoricamente ele está no PIC, e portanto sem sistema operacional.

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 16:12
por edsont
A quantidade de dados já é pequena. Quando se tenta compactar um volume pequeno às vezes acaba ficando maior.

O que a compactação faz é mais ou menos substituir as repetições por um código menor. É um pouco complicado de explicar em poucas palavras.

Na compressão, os dados (bytes) passam a ter quantidades variáveis de bits. Os dados com maior frequencia são codificados com um número menor de bits. E os menos frequentes com mais bits. Para saber qual o último bit de cada dado é feito uma busca numa árvore binária desbalanceada.

Um arquivo compactado precisa ter além dos dados compactados, a árvore de pesquisa para poder ser descomprimida.

Existem outros métodos como a compactação de bits repetidos, mas é mais comum em figuras "chapadas" como bitmaps com poucas cores, neste caso não é necessário a árvore. Só é viável se as repetições ocuparem vários bytes seguidos.

Pode fazer um teste zipando os dados gravados num arquivo pra ver o resultado. Provavelmente o programa vai marcar como compactação zero. E o cabeçalho provavelmente vai deixar o arquivo maior.

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 16:21
por andre_luis
Vamos lá, isso é como eu faria, para seu caso especifico:

Supondo que você está usando o código de ASCII padrão, vai de 32 decimal até 126 decimal, estando de cara limitado em 7bits e não 8bits.
Voce poderia reduzir um pouco mais a faixa, já que os valores não binários ficam restritos á um total de 94 (126-32).
Pelo que vi mais acima, aparentemente NÃO UTILIZA LETRAS, e portanto poderia reduzir ainda mais, para 42 (94 –(2*26)).
Nesse caso, um código de 6 bits poderia mapear todos os caracteres da sua transmissão.
Se você conseguir ainda definir quais outros caracteres não são usados, e se conseguir eliminar mais 10 caracteres ( 42-32 ), consegue comprimir agora para 5 bits apenas, contra os 8 originais

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 16:28
por xultz
Lucas, converter para hexa ou binário é a mesma coisa, é só uma forma de você escrever um determinado número.
A idéia é a seguinte: suponha que eu tenho o número 157. Quando representado em ASCII, ele ocupa três bytes, sendo um para o dígito '1', outro para o dígito '5', e outro para o dígito '7', correto? Caso você não seja muito familiarizado com a tabela ASCII, veja a mesma neste site: http://www.asciitable.com/ e verifique que o código para o dígito '1' é 49 em decimal, ou 0x31 em hexadecimal. Assim, na memória do teu microcontrolador e durante a transmissão destes dígitos no teu pacote TCP, ele seriam (em hexa) 0x31 0x35 0x37, ocupando 3 bytes, certo? Agora, eu posso pegar estes três dígitos e convertê-los para um único valor em decimal, cujo valor é 157, ou 0x9D em hexa, correto? Desta forma, eu ocupo um único byte para armazenar este valor.
Veja um outro exemplo com um número grandão, por exemplo, 57129. Em ASCII, este valor ocupa 5 bytes, um para cada dígito, porém este valor convertido para hexadecimal tem valor 0xDF29. Ou seja, ao invés de 5 bytes, são necessários somente 2 para representar o mesmo valor. Esta é a ideia de converter os valores de ASCII para hexa e economizar alguns bytes (você provavelmente vai economizar mais de 50%).

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 17:24
por barboza
Além da conversão de valores enviados como string para hexadecimal, você pode também enviar o timestamp no padrão UTC.

25/10/2015-23:22:34

No seu exemplo acima, você esta enviando 19 bytes para definir sua data/hora.

Com o UTC, bastam 4 (ou 8 bytes).

https://pt.wikipedia.org/wiki/Tempo_Uni ... Coordenado

http://www.cplusplus.com/reference/ctime/time_t/

Você pode também implementar seu próprio padrão de envio do timestamp. Se não precisa da resolução de segundos, pode enviar os minutos passados desde o ano 2015 por exemplo, ao invés dos segundos após 1970 (UTC).

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 18:25
por edsont
GPRS é tâo caro assim?

Outra dica: deixe os campos com comprimento fixo e elimine os delimitadores ( ; , - / etc.). Em Hexa isso será quase obrigatório. Duh!

Se a frequencia de envio for alta, uma alternativa é usar 2 tipos de pacotes. Um completo e um simples. O completo transmitido a intervalos maiores e o simples sem os dados que variam pouco (como dia, mês, ano) e transmitidos com maior frequencia. Pode usar apenas um bit para identificar o tipo de cada pacote. Ou ainda identificar pelo tamanho.

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 21:09
por KrafT
Se a operadora cobrar pelo encapsulamento TCP, muito pouco pode ser feito para um pacote de dados tão pequeno. É algo como tentar economizar combustível de avião levando menos passageiros.

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 22:22
por lucasromeiro
xultz escreveu:Lucas, converter para hexa ou binário é a mesma coisa, é só uma forma de você escrever um determinado número.
A idéia é a seguinte: suponha que eu tenho o número 157. Quando representado em ASCII, ele ocupa três bytes, sendo um para o dígito '1', outro para o dígito '5', e outro para o dígito '7', correto? Caso você não seja muito familiarizado com a tabela ASCII, veja a mesma neste site: http://www.asciitable.com/ e verifique que o código para o dígito '1' é 49 em decimal, ou 0x31 em hexadecimal. Assim, na memória do teu microcontrolador e durante a transmissão destes dígitos no teu pacote TCP, ele seriam (em hexa) 0x31 0x35 0x37, ocupando 3 bytes, certo? Agora, eu posso pegar estes três dígitos e convertê-los para um único valor em decimal, cujo valor é 157, ou 0x9D em hexa, correto? Desta forma, eu ocupo um único byte para armazenar este valor.
Veja um outro exemplo com um número grandão, por exemplo, 57129. Em ASCII, este valor ocupa 5 bytes, um para cada dígito, porém este valor convertido para hexadecimal tem valor 0xDF29. Ou seja, ao invés de 5 bytes, são necessários somente 2 para representar o mesmo valor. Esta é a ideia de converter os valores de ASCII para hexa e economizar alguns bytes (você provavelmente vai economizar mais de 50%).

Caramba, finalmente entendi...
kkkkkkkkkkk
agora tenho varias duvidas relacionadas a isso...
1- Eu nunca sei qual vai ser o tamanho do meu numero, pode ser 1 ou 3743724 ou outro valor. o hex vai ficar variando de tamanho?
2- Como eu enviaria esses dados? concatenaria todos com "strcat" numa unica string?
3- consegui entender tudo, mas como economiza espaco, pensei em gravar na eeprom assim tambem para economizar espaco na eeprom, o que acha? pensando como fazer isso.

agora estou imaginando como seria a logica de montar um pacote com os dados em hexa todos juntos com a data e tal, formando um pacote completo... para nao fazer m**** e identificar por exempo 0xDF29 como sendo 4 bytes D,F,2,9...

A melhor resposta que tive ate agora!!!
Estou perto de resolver isso!!!

Re: Comprimir dados (ajuda)

MensagemEnviado: 11 Ago 2015 22:34
por lucasromeiro
barboza escreveu:Além da conversão de valores enviados como string para hexadecimal, você pode também enviar o timestamp no padrão UTC.

25/10/2015-23:22:34

No seu exemplo acima, você esta enviando 19 bytes para definir sua data/hora.

Com o UTC, bastam 4 (ou 8 bytes).

https://pt.wikipedia.org/wiki/Tempo_Uni ... Coordenado

http://www.cplusplus.com/reference/ctime/time_t/

Você pode também implementar seu próprio padrão de envio do timestamp. Se não precisa da resolução de segundos, pode enviar os minutos passados desde o ano 2015 por exemplo, ao invés dos segundos após 1970 (UTC).


Exato, me falaram que posso enviar o timestamp no formato de um INT32, ocupando beeeem menos espaco do que ocupa hoje!
Pesquisei, vi exemplos, mas nao achei a forma usada para converter.. a lógica usada na conversao entende?
eu preciso da resolucao de segundos sim, mas posso usar um unsigned int32, me da mais possibilidades...
pode me explicar o funcionamento do utc?
acho que entendi durante a escrita deste texto, basicamente seria a contagem de segundos que se passou desde 1970? rsrs
quando se refere que eu posso fazer meu timestamp quer dizer que posso comecar a contar desde 01/01/2015? boa ideia.
so nao entendi porque eu perco os segundos!!
outra duvida, como eu faco para saber se o ano eh bisexto ou coisas do genero que poderiam bugar o sistema.....
preciso prever isso tudo...