Softperfect Network Scanner v5.4.11 (versão sem limitações)

O Softperfect Network Scanner é um programa da categoria “IP scanner” e dos meus favoritos quando a tarefa é localizar e identificar dispositivos na rede, mas a partir de uma determinada versão o autor decidiu restringir a capacidade da versão gratuita de uma forma que fica inútil para o tipo de uso que faço e para o qual eu o recomendo nos meus blogs. Como a licença da versão antiga explicitamente autoriza a distribuição, aqui está a minha cópia sem essas limitações.

Download “Softperfect_Network_Scanner_v5.4.11” Softperfect_Network_Scanner_v5.4.11.zip – Baixado 1406 vezes – 4 MB

Inclui as versões de 32 e 64 bits e a versão mais recente do arquivo OUI.TXT (para identificação do fabricante dos dispositivos).

 

Como encontrar o fork mais popular ou ativo de um projeto no github

Eu não sei se não soube procurar, mas o github me parece ter uma limitação irritante: ele não mostra na lista de forks a atividade de cada um deles. É comum você se deparar com um projeto interessante mas que não é mais atualizado e querer saber qual de seus forks ainda está ativo ou pelo menos tem mais commits adiante do original. Muita gente faz um fork apenas para “guardar” uma cópia do projeto e quando faz alterações são mínimas.

Aqui você encontra uma solução que não é perfeita mas ajuda muito. Você pode ordenar os forks por número de estrelas, issues, tamanho, data do último push, etc.

Basta preencher a caixa “find” com o identificador do projeto. Por exemplo: gmag11/FSBrowserNG

Mapa de teclado do forno micro-ondas Panasonic Piccolo NN-ST359WRUK

Também serve para o NN-ST359WRUN e NN-ST357WRP (NN-ST357WRPH ou NN-ST357WRPK) . Basicamente todo forno que usar a placa F62607D40AP.

Este mapa não está completo, porque parei ao identificar o que era importante para mim e não quis destruir a membrana original, por isso tive que usar um método menos eficaz.

A numeração começa a partir do display

Combinações úteis para automação
5-4: +1
9-1: Liga
8-1: Cancelar

Todas as combinações

9-1: Liga
9-2: 9
9-3: 8
9-4: 7
9-5: 6
9-6: 5
9-7: 4
9-8: 3

8-1: Cancelar
8-2: 2
8-3: 1
8-4: 0
8-5: Relógio
8-6:
8-7: Terceiro dígito alterna entre 2, 4 e 6

7-1:
7-2: Terceiro dígito exibe 1
7-3: Terceiro dígito alterna entre 1, 2 e 3 (Ovos Mexidos)
7-4: Terceiro dígito exibe 1
7-5: 450_
7-6: Terceiro dígito exibe 1

6-1:
6-2: 650_
6-3: Terceiro dígito alterna entre 1 e 2
6-4: 300_
6-5: 250_
5-1:
5-2: Alterna entre 80 e 160 (Macarrão Instantâneo)
5-3: 100 (Pipoca)
5-4: +1

4-1:
4-2: Descongelar
4-3: Alterna entre 250 e 500 (Auto reaquecimento)

3-1:
3-2: Começa em P10 e vai até P1 (Potência)

2-1:

 

Devo confessar que até olhar o circuito desse forno eu estava trabalhando com a noção antiquada de que todo teclado operava como uma matriz de “x” por “y” fios. Isto é: num teclado de 9 fios teríamos um arranjo máximo de 4×5=20 botões. Problema: o teclado só tinha 9 fios, mas 26 botões.

Em retrospecto, eu percebo que estava preso ao tempo da eletrônica discreta, “burra”, pré-microcontroladores. Com eletrônica discreta você está limitado a determinar que certos fios sejam ligados a “saídas” e que os outros sejam ligados a “entradas” e assim fazer a varredura, ativando as saídas em sequência enquanto monitora as entradas para ver qual foi a acionada. Usando um simples arduino você não está amarrado a isso. Durante a execução do programa você pode fazer com que o mesmo pino alterne entre entrada e saída e quando você tem 9 pinos que são capazes de fazer isso, você acaba tendo 36 possibilidades.

Saber as combinações possíveis nesse caso é um problema de análise combinatória. Você não precisa conhecer a matemática para um número de possibilidades tão pequeno, porque pode obter todas elas em um minuto escrevendo em um papel. Mas a fórmula é a seguinte:

f! / ((f – 2)! * 2!)

Onde f é o número de fios que vai para o teclado e 2 é o número de fios que unimos para obter um comando.

Como são 9 fios, temos 9! / ((9 – 2)! * 2!) = 36 combinações possíveis

Das quais no final do teste descobri que apenas 29 são usadas, o que é curioso, porque o teclado original tem 26 botões. A placa permite fazer alguma coisa a mais que o que está disponibilizado nesse modelo.

Você pode usar esta calculadora online para fazer o cálculo. Responda “No” às duas perguntas e preencha N=9 e M=2.

Dicas sobre como determinar que combinações correspondem a que comandos (se você não quiser ou não puder destruir a membrana original)

Elabore antecipadamente uma lista das combinações possíveis em papel, em uma coluna do lado esquerdo. Com um pedaço de fio, vá testando cada combinação mais de uma vez seguida enquanto anota do lado direito o que aparece no display. Isso é importante, porque alguns botões apresentam valores diferentes ao serem pressionados repetidas vezes e comparar esse comportamento com o que está escrito no manual vai ajudar a determinar a função. Além disso, seguindo um roteiro você evita perder tempo testando mais de uma vez a mesma combinação.

Combinações que não exibem nada mas geram um bip são importantes. Anote “bip”. Por exemplo, apertar os botões “liga” e “cancelar” neste modelo de micro-ondas sem ter apertado nenhum outro botão antes não parece gerar nenhuma resposta no display. Apenas um bip.

No meu caso, para descobrir quais os botões que apenas bipavam eram os botões “liga” e “cancelar” a ajuda do manual foi muito importante. Ele dizia que após apertar o botão liga três vezes seguidas o teclado era travado e um símbolo específico era exibido no display . E que para cancelar isso era preciso apertar o botão cancelar três vezes. Então, quando terminei minha lista eu só precisei testar três vezes cada uma das combinações que apenas bipavam até o símbolo aparecer. Esse era o botão “liga”. Depois disso testei todas as combinações restantes até o símbolo desaparecer. Esse era o botão “cancelar”.

Achar o botão “+1” também pode te ajudar nisso. No meu caso, o resultado de apertar essa botão repetidas vezes é aparecer em sequencia: 1 00, 2 00, 3 00, 4 00, 5 00, 6 00, 7 00, 8 00, 9 00 e 1 000 no display. Inicialmente eu pensei que esse botão estivesse inserindo o peso do alimento, mas na verdade “1 00” significa “1:00” e assim por diante.  Se você achar o botão +1, qualquer outro botão que você simular em seguida que ligar o relê da placa é o o botão “liga”.

Combinações que não geram nenhuma resposta, nem mesmo um bip, devem ser marcadas de acordo para você não perder tempo com elas. A não ser no final quando estiver faltando alguma função. Por exemplo, se o teclado do forno tem 26 botões e vocês só encontrou alguma resposta em 25 combinações, uma dessas que não deu resposta deve ter sido mau contato.

 

Tutorial MongoDB Atlas: conta, bancos e coleções

Neste tutorial vamos usar uma conta gratuita MongoDB Atlas, que é limitada a 500MB (04/2020) de dados.

Visite https://www.mongodb.com/cloud/atlas e clique em Start Free (1). Na próxima página você pode se registrar usando uma conta Google ou email, nome, sobrenome e senha (2). Essas
são as únicas informações pedidas e pelo menos até abril de 2020 não era pedida confirmação do email até a data deste trabalho. Preencha tudo como no exemplo e clique em Get Started Free (3):

mongodb_atlas_1_automalabs.com.br

Agora clique em Create a Cluster – FREE para criar uma conta gratuita

mongodb_atlas_10_automalabs.com.br

Na próxima tela você escolhe o provedor de nuvem e a localidade. O default (no caso abaixo, um servidor Amazon na Virgínia do Norte) é suficiente. Clique em Create Cluster.mongodb_atlas_10_automalabs.com.br

A seguir MongoDB Atlas vai instalar e configurar o MongoDB no provedor de nuvem escolhido. Esse processo pode levar alguns minutos e você deve esperar enquanto os avisos, em inglês, estiverem aparecendo na tela:

mongodb_atlas_10_automalabs.com.br

Quando os avisos sumirem você pode passar para o próximo passo, que é criar um usuário. Clique em Create your first database user.

mongodb_atlas_10_automalabs.com.br

Clique em Database Access:

mongodb_atlas_10_automalabs.com.br

Clique em Add New Database User:

mongodb_atlas_10_automalabs.com.br

Na próxima tela não altere as opções padrão. Insira um nome de usuário (1), senha (2) e clique em Add User.

mongodb_atlas_10_automalabs.com.br

Esse usuário vai ser criado com permissões para ler e escrever em qualquer banco de dados, mas não vai poder administrar o banco de dados. Isso é o bastante para nossa aplicação.

Agora clique em Whitelist your IP addres:

mongodb_atlas_10_automalabs.com.br

Clique em Network Access:

mongodb_atlas_10_automalabs.com.br

Clique em Add IP Address:

mongodb_atlas_10_automalabs.com.br

Você pode clicar em ADD CURRENT IP ADDRESS (1) para colocar o seu endereço IP externo público, mas a menos que você esteja em uma conexão que tem IP fixo esse IP vai mudar pelo menos toda vez que você reiniciar seu modem. Pelo menos durante a fase de aprendizagem é melhor clicar em ALLOW ACCESS FROM ANYWHERE (2), que vai dar acesso ao banco de dados de qualquer lugar (adiciona 0.0.0.0/0, como mostrado). Finalize clicando em Confirm (3).

mongodb_atlas_10_automalabs.com.br

O próximo passo da lista, Load Sample Data, é opcional, mas pode ser interessante. Ele carrega no banco de dados algumas coleções de documentos de exemplo que você pode usar enquanto está
aprendendo MongoDB. Ocupa mais da metade do espaço disponível no serviço gratuito, mas não vamos precisar de muito espaço neste projeto. De qualquer forma este tutorial vai prosseguir sem
esse passo opcional. Você terá outras oportunidades de carregar essas coleções.
Também não vamos precisar do passo Connect your Cluster, porque vamos usar o serviço Stitch. Então finalize o assistente clicando em No thanks:

 

mongodb_atlas_14_automalabs.com.br

Em seguida clique em Dismiss it:

mongodb_atlas_15_automalabs.com.br

 

Agora nós vamos criar uma coleção. Isso não é estritamente necessário porque, como veremos adiante, a coleção é automaticamente criada quando necessário. Mas mostraremos como é feito
assim mesmo. Em um banco de dados orientado a documentos uma coleção é o equivalente a uma tabela em um banco relacional.
Clique em Collections:

 

mongodb_atlas_10_automalabs.com.br

Clique em Add My Own Data:

mongodb_atlas_10_automalabs.com.br
Dê um nome para o banco de dados (1), um nome para a coleção (2) e clique em Create (3):

mongodb_atlas_10_automalabs.com.br

 

Para criar um novo banco de dados, clique em Create Database (1). Para criar uma nova coleção mova o mouse sobre o nome do banco de dados e clique no sinal + que aparece (2).

mongodb_atlas_10_automalabs.com.br

Pronto. Você já tem o necessário para criar o equivalente a bancos e tabelas no MongoDB. Em outros posts eu explicarei como inserir dados nesse banco usando um ESP8266 e como extrair dados dele usando o Delphi.

Introdução aos bancos de dados NoSQL

Nota do autor: Este texto foi originalmente escrito para um projeto de 73 páginas (inclui figuras e código-fonte) que fiz na faculdade intitulado BANCO DE DADOS ORIENTADO A DOCUMENTOS – UMA APLICAÇÂO PRÁTICA e seguiu alguns requerimentos burocráticos que eu apaguei e outros que mantive. O projeto completo inclui uma aplicação em Delphi para Windows e outra para Arduino/ESP8266 e será tudo detalhado em outros posts.

 

Quando pensamos hoje em banco de dados quase sempre ainda estamos pensando em um banco de dados relacional. Segundo pesquisa mensal da consultoria austríaca Solid IT, os
quatro SGBD (Sistema Gerenciador de Banco de Dados) mais populares são relacionais, o que corresponde a 75% do total.
db-engines_database_ranking_automalabs.com.br

O que pode surpreender muitos programadores que por não conhecerem as alternativas podem se espantar por esse número não ser 100%. Mas provavelmente todo programador deve ter se deparado com alguma situação em que seu SGBD (relacional) favorito gerava um incômodo que precisou ser contornado de alguma forma pouco ou nada elegante e que poderia ter sido resolvido com a troca do paradigma.

Mas antes de introduzir a alternativa é conveniente dar um exemplo do tipo de problema que ela resolve.

Considere um problema comum de IoT (Internet of Things – Internet das Coisas) onde você tem um sensor para acompanhar o desenvolvimento minuto a minuto de uma certa grandeza (temperatura, por exemplo) e deseja armazenar isso em um banco de dados para análise posterior. A informação mínima útil a armazenar seria a temperatura e o horário da medição. Uma representação tabular da informação armazenada ficaria assim:

Ordem Temperatura Horário
1 22,12 01/05/2020 15:10
2 23,45 01/05/2020 15:11
3 25,10 01/05/2020 15:12
4 26,13 01/05/2020 15:13

Mas digamos que em um momento qualquer no futuro você decidiu acrescentar mais um sensor. Em uma aplicação convencional usando um SGBD relacional, além de ter que atualizar todos os componentes do projeto que acessam o banco de dados é preciso alterar o próprio banco de dados mudando o seu schema (sua estrutura lógica) acrescentando no mínimo uma coluna (campo), e o resultado poderia ser algo assim:

Ordem Temperatura Horário Temperatura2
1 22,12 01/05/2020 15:10
2 23,45 01/05/2020 15:11
3 25,10 01/05/2020 15:12
4 26,13 01/05/2020 15:13
199 25,12 20/05/2020 11:00 28,10
200 26,13 20/05/2020 11:01 29,05
201 27,08 20/05/2020 11:02 30,12
202 29,10 20/05/2020 11:03 31,10

 

O fato de todos os registros anteriores à alteração ficarem vazios pode ou não ser um problema, mas o fato de ter que alterar o schema é. Além do mero incômodo de ser um passo adicional, normalmente alterar o schema requer downtime. Todos os acessos à tabela a modificar precisam ser interrompidos durante a operação. Em um sistema local isso pode significar apenas “pedir a todo mundo que saia do sistema”, mas à medida que aumenta a complexidade e a utilização do sistema, interromper o acesso aos dados mesmo que por um intervalo curto de tempo vai se tornando uma decisão mais difícil, impactando negativamente na escalabilidade. Sam Saffron, um dos criadores do popular software de código aberto de gerenciamento de listas de discussão Discourse, afirma que “uma das razões mais comuns para interrupções de serviço durante o deployment de uma aplicação é a alteração do schema do banco de dados”.

Agora digamos que você como desenvolvedor antecipa a necessidade futura de acrescentar sensores e pensando em evitar esse passo adicional e o downtime, decide criar a tabela já com os campos necessários para acomodar mais sensores. Mas quantos campos adicionais antecipar? Dois? Cinco? Dez? Cem? E se você precisar fazer alguma alteração que torne essa antecipação inútil? O nosso exemplo é propositalmente bem simples, mas existem outras situações similares bem mais complexas.

Nesse ponto é interessante avaliar os SGBD NoSQL.
Bancos de dados NoSQL

NoSQL é um paradigma de banco de dados que é modelado de uma forma diferente da tradicional representação tabular dos bancos relacionais. Esse tipo de banco de dados existe desde os anos 1960, mas apenas cerca de dez anos atrás foi o adotado o termo “NoSQL” para se referir ao paradigma.  Bancos NoSQL tem um foco em simplicidade de projeto e escalabilidade e suas estruturas de dados são diferentes das usadas em bancos relacionais fazendo com que algumas operações sejam mais rápidas em NoSQL.

Os requerimentos do nosso exemplo são a capacidade de mudar o schema facilmente e fazer buscas simples no banco de dados. O primeiro é uma característica dos bancos NoSQL mas os recursos de busca dependem do SGBD NoSQL escolhido.

Os SGBD NoSQL podem ser divididos em quatro grandes categorias:

  • Chave-Valor (key-value);
  • Armazenamento de Documentos (document-store);
  • Armazenamento de coluna ampla (wide colum stores);
  • Graph Database.

Novamente usando como referência  a DB-Engines, podemos ver que os modelos mais populares são chave-valor e armazenamento de documentos:

db-engines_database_ranking_automalabs.com.br

Por brevidade, vamos nos ater a analisar apenas esses dois modelos.

Chave-Valor
Nesse modelo o banco de dados usa um simples método chave-valor para armazenar os dados. É mais fácil entender esse método pensando que um dicionário é um exemplo de chave-valor: a chave sendo uma palavra e o valor sendo o significado. O nome do método pode ser enganador, levando você a pensar que o “valor” pode ser uma entidade apenas, mas não é bem assim. Abaixo temos um exemplo perfeitamente válido de armazenamento chave-valor:

Chave Valor
1 22.5,10/04/2020 12:35
2 23.6,10/04/2020 12:36
3 24.2,10/04/2020 12:37
4 25.1,10/04/2020 12:38

No exemplo acima, cada chave dá acesso a duas entidades: uma temperatura e o horário. Chave-valor não tem nenhum schema definido e você está livre para mais tarde ao descobrir que precisa colocar mais um sensor fazer algo assim:

Chave Valor
1 22.5, 10/04/2020 12:35
2 23.6, 10/04/2020 12:36
3 24.2, 10/04/2020 12:37
4 25.1, 10/04/2020 12:38
199 27.2, 20/05/2020 17:23, 28.9
200 28.4, 20/05/2020 17:24, 27.9
201 27.3, 20/05/2020 17:25, 26.5
202 26.2, 20/05/2020 17:26, 25.3

Como se pode ver, o valor do segundo sensor foi simplesmente acrescentado aos novos registros armazenados. Isso pode ser feito indefinidamente e não apenas com o valor de outros sensores. Você pode adicionar qualquer outra informação ao registro que queira, como notas. Você faz o seu schema e isso é transparente para o banco de dados.
Além disso, como a única coisa que define a chave é que é um valor que só pode ocorrer uma vez no banco de dados, você pode perfeitamente usar o horário como chave:

Chave Valor
10/04/2020 12:35 22.5
10/04/2020 12:36 23.6
10/04/2020 12:37 24.2
10/04/2020 12:38 25.1
20/05/2020 17:23 27.2, 28.9
20/05/2020 17:24 28.4, 27.9
20/05/2020 17:25 27.3, 26.5
20/05/2020 17:26 26.2, 25.3

Parece perfeito para a nossa aplicação, mas existe um problema. Segundo a IBM Cloud Education:

Em geral, armazenamentos key-value não tem linguagem de consulta. Eles simplesmente proporcionam um modo de armazenar, recuperar e atualizar dados usando simples comandos GET, PUT e DELETE. A simplicidade deste modelo torna um armazenamento key-value rápido, fácil de usar, escalável, portável e flexível.

Então com satisfazer o requerimento de poder fazer buscas no banco? De acordo com DB-Engines, o mais popular SGBD com suporte a chave-valor é o Redis:

db-engines_key-value_stores_ranking_automalabs.com.br

Este parece suportar buscas, mas após uma verificação superficial da documentação não conseguimos uma resposta clara de como fazer o tipo de busca que desejamos.

Armazenamento de Documentos

Esse nome pode dar a impressão inicial que essa categoria objetiva armazenar arquivos do Word, Excel, AutoCAD, etc. Os arquivos que nós geralmente chamaríamos de “documentos” em um computador. Mas não se trata disso. No contexto dos bancos de dados um documento pode ser algo tão simples quanto a seguinte linha de texto:

{“Temperatura1”:”22.4”}

De acordo com DB-Engines, o mais popular SGBD orientado a documentos é o MongoDB:db-engines_document_stores_ranking_automalabs.com.br

Em teoria você pode armazenar o documento em qualquer formato que queira, mas se você quer aproveitar as vantagens do NoSQL é prudente seguir formatos padronizados e cada SGBD tem suas preferências, sendo os mais comuns XML e JSON. Abaixo uma comparação simples dos dois formatos:

XML JSON
<temperatura1>22.4</temperatura1>

<horário>10/12/2019 10:23</horário>

{“temperatura1”:”22.4”;

“horário”:” 10/12/2019 10:23”}

Como se pode notar o formato JSON é mais “natural”, mais fácil de ler e menos “verboso”, isto é: requer menos texto para transmitir a mesma informação. E de fato o mais popular SGBD NoSQL, o MongoDB, optou pelo JSON. E acabamos optando por esse também.

Os documentos não seguem nenhum schema rígido, por isso você pode a qualquer tempo adicionar novos campos ao documento, como no exemplo abaixo:

JSON
{“temperatura1”:”22.4”;

“horário”:” 10/12/2019 10:23”}

{“temperatura1”:”23.7”;

“horário”:” 10/12/2019 10:24”}

{“temperatura1”:”23.7”;

“temperatura2”:”24.2”;

“horário”:” 10/12/2019 10:25”}

{“temperatura1”:”23.7”;

“temperatura2”:”24.8”;

“horário”:” 10/12/2019 10:25”}

 

No exemplo nós simplesmente acrescentamos um campo a mais: temperatura2, mas novos campos podem ser acrescentados indefinidamente. Quanto ao nosso requerimento de fazer buscas nos dados, a documentação do MongoDB nesse aspecto é muito mais fácil de entender que a do Redis.

É importante notar que, mesmo usando JSON, document-store desperdiça muito espaço em comparação com um banco de dados relacional ou mesmo o modelo chave-valor por causa da alta repetição de informação. Por exemplo, digamos que desejamos apenas armazenar o valor em ponto flutuante de dois sensores no formato: “12,34” e que esse valor seja armazenado como string ASCII (cinco bytes por valor armazenado). Vamos considerar um “id” para identificar o registro, também string, com dois bytes:

Banco Relacional:

Id Sensor1 Sensor2
01 23,34 23,45

Cada registro ocupa 12 bytes

Agora, o mesmo registro codificado como JSON:

{
“Id”=”01”
“Sensor1”:”23,34”;
“Sensor2”:”23,45”;
}
Como cada caractere precisa ser contado, a mesma quantidade de informação ocupa agora (ignorando caracteres de quebra de linha) 47 bytes por registro.  Essa diferença só piora à medida que mais valores precisarem ser armazenados em cada documento. Em muitas aplicações essa diferença é irrelevante diante das vantagens, mas precisa ser levada em consideração onde espaço é problemático, como nas aplicações embarcadas. Espaço não será problema na nossa demonstração, pois mesmo na versão gratuita, com 500MB de espaço, o serviço escolhido pode suportar nossos requerimentos básicos por mais de três anos.

Podemos reduzir essa desvantagem no uso de espaço usando um formato binário de codificação como o BSON, mas em alguns casos BSON pode ocupar ainda mais espaço que JSON porque, de acordo com o FAQ “…adiciona informação extra aos documentos, como o comprimento das strings e subobjetos” e tem a desvantagem de não ser uma codificação legível por humanos.

 

Suporte a relações

Apesar de NoSQL se referir especificamente a bancos de dados não relacionais achar que você não pode armazenar relações em um bancos de dados NoSQL é um engano. Segundo a MONGODB, Inc: “Um equívoco comum é achar que bancos de dados NoSQL ou bancos de dados não-relacionais não armazenam dados de relacionamento bem. Bancos de dados NoSQL podem armazenar dados de relacionamento – eles apenas o fazem diferentemente de como é feito pelos bancos de dados relacionais. 

Então não existe problema se futuramente nosso projeto necessitar de suporte a relações.

Diante do exposto, decidi pelo uso do modelo Armazenamento de Documentos com o MongoDB como SGBD.

Para demonstrar o uso de NoSQL irei usar um Arduino com dois sensores de temperatura publicando uma vez por minutos as temperaturas em um servidor NoSQL MongoDB Atlas e uma interface de usuário Windows onde se pode coletar e analisar esses dados. O projeto inteiro foi desenvolvido em três linguagens: javascript nos scripts Atlas, Delphi na aplicação Windows que fornece a interface gráfica com usuário e C++ no programa que roda no Arduino.

Nesta aplicação foi descartado o uso de um servidor de banco de dados NoSQL local porque reduziria sua utilidade. Dentre as opções online optamos pelo MongoDB por oferecer um serviço gratuito na forma do MongoDB Atlas. A única limitação dessa versão gratuita que afeta nossa demonstração é estar limitada a 500MB.

Próxima parte: Criando e configurando uma conta MongoDB Atlas

ESP8266: error: call of overloaded ‘println(time_t (&)())’ is ambiguous

Esse erro pode acontecer por diversas razões, mas no meu caso foi porque eu estava trabalhando em um exemplo feito por outra pessoa onde o desenvolvedor criou uma variável local chamada “now”. Eu fiz uma modificação acidental que escondeu a declaração da variável e então em vez do compilador me avisar disso ele assumiu que todas as referências a “now” no código fossem as declaradas em bibliotecas como a Time.h, que tem variáveis com o mesmo nome. E ele não sabia qual usar.

O compilador não tem como adivinhar sua intenção nesse caso.

A solução foi consertar a declaração que eu havia apagado, mas melhor ainda foi substituir todas as ocorrências de “now” no código por “agora” para evitar acidentes como esse no futuro. Eu acho que nós brasileiros levamos uma pequena vantagem nesse caso por usarmos naturalmente nomes de variáveis em português, o que evita a colisão com os nomes usados em bibliotecas, que geralmente estão em inglês. Se o nome da variável não fosse “now” minha ocultação acidental da declaração teria apenas causado um erro facílimo de entender do tipo “não foi declarada”. Tenha em mente que se o compilador tivesse encontrado apenas uma alternativa e assim não tivesse ficado confuso compilaria o código e eu estaria usando no meu programa o conteúdo da variável errada (a de uma biblioteca em vez da local) o que levaria a defeitos difíceis de debugar.

Como criar um ícone transparente de alta resolução para uso no Delphi 7

Este tutorial requer que você saiba o básico de edição de imagens (selecionar, recortar, redimensionar, etc). Eu não vou entrar em muitos detalhes aqui.

Para tornar o fundo da imagem transparente

Para este tutorial eu vou usar a imagem de uma engrenagem que pode ser obtida aqui. Eu recortei antes de começar o tutorial o que não era necessário para mim, o que incluía a sombra.

Usando o Paint.Net (estou usando a versão 4.2.1), selecione a região a tornar transparente. Usando a ferramenta Varinha Mágica, por exemplo, você usa SHIFT+CLICK para selecionar mais de uma região e reduz a Tolerância (indicada pela seta) se o corte automático estiver invadindo uma região que não deve. No exemplo abaixo dei um clique para selecionar a região externa e outro para selecionar a região no centro da imagem:

PaintNet_MagicWand_automalabs.com.br

Tecle DEL para apagar a região selecionada. O Paint.Net já mostrará que está definido como transparente usando o padrão xadrez característico.

PaintNet_TransparentCog_automalabs.com.br

Agora salve como PNG.

Se você precisa criar uma transparência mais complexa, pode usar o plugin Cut Color

Uma alternativa online ao Paint.Net para a criação da transparência está aqui.

Converter o arquivo PNG para ICO usando o Icon Workshop

Obs.:

  • Neste tutorial eu estou usando o Icon Workshop 6.53;
  • É possível que o Icon Workshop tenha ferramentas embutidas para definir a transparência sem precisar de ferramentas extras, mas nesse momento eu não sei como fazer e por isso usei o Paint.Net;
  • Tenha me mente que um arquivo ICO é uma coleção de imagens. Ele pode conter apenas uma, mas também pode conter muitas, que são selecionadas pelo Windows de acordo com a necessidade.

Você precisa abrir o arquivo PNG no Icon Workshop (IW). Isso pode ser feito de diversas maneiras:

  • CTRL-G para a busca de mídia;
  • Clicando no botão Browse;
  • ou arrastando a imagem para a janela do IW.

iconWorkshop_ImageLoaded_automalabs.com.br
Na janela onde aparece a imagem, clique no ícone no canto superior esquerdo. Aquele que tem um “I”:

IconWorkshop_ConvertToIco

O IW te mostrará todas as opções de criação para Windows:

 

IconWorkshop_AsNewIcon_automalabs.com.br

Se você vai usar sua aplicação em um sistema do Windows Vista em diante, marque a caixa indicada pela primeira seta.

Se o PNG for salvo dentro do ICO (um arquivo ICO é uma coleção de imagens) como compressed PNG o Delphi não poderá usá-lo e poderá até não conseguir compilar mais, acusando erro RLINK32: Out Of Memory. Então você precisa desmarcar a caixa apontada pela seta inferior.

Clique em OK, a imagem aparecerá no IW agora como um conjunto de imagens:

IconWorkshop_IconePronto_automalabs.com.br

Atente para as miniaturas. Se alguma (geralmente a primeira) exibir um símbolo de compressão alguma coisa deu errado e a imagem ainda está como PNG Compressed. Clique com o botão direito sobre a miniatura e desmarque a opção indicada.

IconWorkshop_PNGCompressed_automalabs.com.br

Agora você já pode salvar o ícone e carregá-lo no Delphi 7.

 

Não consegue usar o Icon Workshop?

Existem ferramentas online como icoconvert.com que fazem a criação do ícone para você. Se você fizer o upload do PNG do nosso exemplo e escolher a opção “ICO for Windows 7, Windows 8, Vista and XP” o site te devolverá um arquivo ICO com 5 imagens (256×256, 48×48, 32×32, 24×24 e 16×16, todas RGB/A). Porém a primeira imagem está comprimida e o ICO será incompatível com a compilação no Delphi 7. Você poderá, entretanto, carregar esse ícone manualmente no arquivo EXE da aplicação usando o Resource Hacker.

Já se você escolher Custom sizes -> Multi sizes e selecionar apenas as opções 48×48, 32×32, 24×24 e 16×16 (abrir mão do ícone de 256×256) o resultado poderá ser compilado pelo Delphi 7.

Delphi: Como atualizar a área de trabalho programaticamente

Se você estiver experimentando novos ícones para a sua aplicação pode ser enganado pelo fato do Windows manter um cache com os ícones apresentados no desktop e assim os ícones nos atalhos podem permanecer os mesmos até pelo menos o Windows ser reiniciado.

Para forçar o Windows a recarregar todos os ícones, acrescente shlobj na seção USES do form e dê o seguinte comando:

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);

Você deverá notar o desktop “piscar”.

Testado com Delphi 7 e Windows 8.1 64 bits.

 

Delphi 7: Erro RLINK32 Out Of Memory ao tentar trocar um ícone

Abra o ícone que você está tentando inserir no Icon Workshop ou outro editor de ícones e verifique se uma ou mais das imagens (um arquivo .ICO pode conter várias) não está em um formato comprimido como “PNG Compressed”. Se estiver, desmarque a opção, salve e recarregue o ícone no Delphi. Isso é suportado pelo Windows Vista em diante mas o Delphi 7 não sabe como manipular.

Módulo para leitura de células de carga HX711

modulo_hx711_DSC03192_640_automalabs.com.br

Datasheet do CI HX711

Se você precisa medir peso com o Arduino esse é o módulo geralmente requerido. Permite conectar até dois conjuntos de células de carga (duas balanças).

Trata-se essencialmente de um amplificador de instrumentação de duas entradas multiplexadas incorporado a um conversor A/D de 24 bits. O que permite uma resolução muito superior à que seria obtida ligando um amplificador de instrumentação diretamente a uma entrada analógica do Arduino, cujo conversor A/D é de 10 bits.

  • Alimentação de 2.7 a 5.5V;
  • Saída digital a dois fios;
  • Duas entradas multiplexadas. Você pode usar apenas a entrada A, se quiser;
  • Taxa de amostragem selecionável de 10 ou 80 amostras por segundo;
  • Ganho selecionável de 32, 64 e 128.

Este é o o diagrama / esquema do módulo:

hx711_module_diagram_2

É quase a mesma coisa que o diagrama típico apresentado no datasheet, com o acréscimo de C4, C5, C6, R8 e R9.

Note que existem duas referências de terra: GND e AGND

Como fazer a leitura

O valor do registrador de 24bits com o resultado da medição é lido serialmente dando 24 pulsos no pino SCK e coletando os bits no pino DT. Isso é realmente simples de fazer mesmo sem uma biblioteca, mas como elas existem vamos usá-las até porque torna o código mais fácil de entender.

A biblioteca de uso mais simples que conheço é a do chinês aguegu. Você precisa fornecer à biblioteca quatro informações:

  • qual o pino de clock;
  • qual o pino de dados;
  • o valor de offset;
  • o valor do ratio.

Você pode usar dois pinos quaisquer. A biblioteca usa nos exemplos os pinos A0 e A1 mas estes são usados no modo digital. Pinos analógicos não são requeridos.

O valor de offset é o valor que o HX711 fornece quando a balança está em repouso (seria o “zero” da balança). Para obtê-lo deixe a balança sem peso e rode o seguinte sketch:

O valor impresso na serial pelo sketch é o offset. É normal que seja um valor grande como 8447426. Note que esse valor é aproximadamente metade de 16777215 (o maior valor possível com 24 bits). Isso é esperado porque o hx711 também lê valores negativos. Agora coloque um peso conhecido na balança, como 1kg (1000g), e execute novamente o sketch acima para obter o que a balança vê agora. Esse valor deve ser maior que o valor obtido de offset. Se não for, experimente inverter os fios S+ com S- e repita. Vamos chamar esse novo valor de “w”. Agora faça a seguinte conta para obter o ratio:

ratio = (w - offset) / 1000

E preencha os valores obtidos no sketch abaixo:

O programa de exemplo acima deverá agora dar o valor aproximado de qualquer peso medido, em gramas.

Nota: a biblioteca tem um bug que faz a execução ser muito lenta. Para corrigir, abra hx711.cpp e os exemplos e mude todas as referências a averageValue() para averageValue(1). Isso na prática anula a função averageValue(), mas elimina o retardo. É melhor você tirar sua própria média dos valores lidos no loop (sugiro uma média móvel) para evitar paradas desnecessárias na execução do programa.