Guia CNC Brasil - Tudo sobre CNC, Router, Laser, Torno e 3D Print

ELETRÔNICA / ELÉTRICA => Eletrônica Básica => Programação => Tópico iniciado por: matrixlan1 em 02 de Outubro de 2009, 11:33

Título: CLOCK em microsegundos
Enviado por: matrixlan1 em 02 de Outubro de 2009, 11:33
Ola amigos da programação, estou programando um sinal de clock na porta paralela para acionar o motor a passo na CNC3AX, que é o seguinte:

outport(0x378, 2); pino 2 da porta paralela em nivel "1")
sleep(10) causa atraso de 10 ms
outport(0x378, 0); (pino 2 da porta paralela em nivel "0")
sleep(10) causa atraso de 10 ms

as linhas do programa acima se  repetem de "1" para "0" numa frequencia determinada pelo comando sleep()

o L297 recebe os pulsos normalmente so que com baixa rotação no motor.

quando ligo a cnc3ax no mach2 o motor roda em toda sua potencia, com isso me conscientizei que o erro pode estar no meu codigo.alguem pode me da uma força?

percebi que o mach2 trabalha numa frequencia muito nais alta do que e apenas ms (milisegundo) ele deve trabalhar em us(microsegunds).
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 02 de Outubro de 2009, 13:02

Qual versão de Windows está usando?

O Windows só roda o seu programa?

Coloque um frequencímetro ou osciloscópio no pino que vai para o L-297. Ajuste o delay em seu programa para 1000ms (Ton e Toff) e vá baixando de 100 em 100ms e meça a frequência. Quando chegar em 100ms baixe de 10 em 10 ms. Meça e informe os resultados...

Veja se o motor acompanha a temporização ajustada, de maneira coerente na rotação, voce pode medir a rotação usando um frequencímetro e um sensor óptico.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 02 de Outubro de 2009, 16:30
"Qual versão de Windows está usando?"

estou usando o wundows XP

"O Windows só roda o seu programa?"

nao, meu windows roda outros tambem, inlusive testo a cnc3ax nele

"Coloque um frequencímetro ou osciloscópio no pino que vai para o L-297. Ajuste o delay em seu programa para 1000ms (Ton e Toff) e vá baixando de 100 em 100ms e meça a frequência. Quando chegar em 100ms baixe de 10 em 10 ms. Meça e informe os resultados..."

com ajuste de 1000ms (1 segundo) o motor da giros bem demorados, de 1 em 1 segundo e funciona bem, fui baixando o delay como voce disse o maximo que se consegue é 1ms, o motor vai girando cada vez mais rapido (mais raquiticamente) a rotação nem se compara com a do mach2, que é pelo menos 10x mais rapido, acredito que esse programa não emita clock para CNC3AX em milisegundos e sim em microsegundos, por isso ele consegue velocidades mais rápidasno motores do que o meu programa, mas pude observar o C++ não tem microsegundos só milisegundos.

Voce por acaso teria alguma rotina em C++com delay em microsegundos?

abaixo esta a largura dos pulsos que uso e mais a frentena mesma foto a do L297

Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 02 de Outubro de 2009, 16:56
Matrixlan1,

Qual o seu nome? O meu é Gil...

O que voce quer dizer com "rodar raquiticamente"? Devagar(lento) ? Ou com pouco torque?

É complicado tentar temporizar com microssegundos usando o Windows, é algo do tipo: "me engana que eu gosto"...  :)

Desconheço alguma instrução do compilador que temporize abaixo de 1 ms.

Mas pense no seguinte... o comando sleep gasta um certo tempo do processador, mas o tempo do processador também pode ser "gasto" de outras maneiras. Tente retirar o comando sleep, aí a temporização entre o nível 1 e o nível 0 será a quantidade de instruções (ciclos de máquina) do processador + latência do Windows. Será algo bem pequeno mas talvez imprevisível, devido ao Windows, que passa a ser "o fator limitante".

Se voce colocar uma instrução do tipo a=10 também gasta tempo do processador. Não sei te dizer quanto, mas gasta, teria que medir (usando um osciloscópio). Depende de como o compilador traduziu em códigos de máquina, da velocidade do processador,... Programação neste nível requer ferramental e saber o que está fazendo e como toda a coisa funciona (Sistema Operacional, o Procesador do PC, a Porta Paralela,...), neste nível de microssegundos, a coisa não se resume ao compilador e às instruções do programa em C.

Mas se voce quiser mesmo tentar temporizar em microssegundos, indo além, deverá usar comandos em assembly no meio do seu código C. Não sei se o C++ Builder aceita isso, por exemplo, existe um comando do compilador Turbo C (em DOS) que permite inserir uma ou mais linhas de código assembly num programa em C, mas aí a coisa começa a ficar cabeluda!! Essas linhas não são compiladas, mas executadas diretamente pela CPU...

O certo mesmo seria fazer a parte que exige velocidade do código em assembly e aí linkar essa parte com o resto do programa.

Outra opção é fazer programa multitarefa em tempo real (usando o RT-Linux) e criar uma Task ou uma Thread em assembly, rodando de maneira concorrente com os outros módulos (tarefas) do programa de alto nível. É assim que os programas profissionais funcionam.

Em resumo, se queres mais velocidade, tem que ir além... usar assembly, dominar a máquina, o sistema operacional...
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 03 de Outubro de 2009, 13:23
Qual o seu nome? O meu é Gil...[/i]

ola GIL meu nome é Odail, prazer em conhecer

O que voce quer dizer com "rodar raquiticamente"? Devagar(lento) ? Ou com pouco torque?[/i]

O motor roda muito devagar em relação a outro de uma maquina cnc que roda em 10x a mais

É complicado tentar temporizar com microssegundos usando o Windows, é algo do tipo: "me engana que eu gosto"...  :)

verdade amigo, eu estava fazendo uma pesquisa no google sobre isso e tem pouca coisa sobre o assunto mas eu achei em linguagem "C" o comando usleep() que funciona em micro segundos (é isso que procuro)mas eu fui ver no C++ Builder e ele nao tinha esse comando, so tinha o sleep() comum.

Desconheço alguma instrução do compilador que temporize abaixo de 1 ms.

em interface C++ é ate dificil mesmo mas em compiladores para PIC por exemplo tem essa função e ja usei bastante, e o mais interessante é que funciona....

Tente retirar o comando sleep, aí a temporização entre o nível 1 e o nível 0 será a quantidade de instruções (ciclos de máquina) do processador + latência do Windows.

ja coloquei "0" nos delays ele simplesmente nao funcionam o motor fica parado??


Se voce colocar uma instrução do tipo a=10 também gasta tempo do processador. é exatamente isso que estou fazendo dentro do meu delays declarei uma variavel chamada:

int tempo;

depois dentro do delay (sleep):

sleep(tempo)

a variavel "tempo" esta adicioanada em um botão SLIDER no C++ BUILDER (tipo aqueles de volume de audio) toda vez que que aumento esse SLIDER ele incrementa ou decrementa a variavel "tempo" neese caso as variaveis quando se acrescenta um valor tipo: tempo=10; ela vai atrasar 10 milisegundos...

Mas se voce quiser mesmo tentar temporizar em microssegundos, indo além, deverá usar comandos em assembly no meio do seu código C.

Assembly é muito massa de programar muitos dizem isso, mas eu sinceramente teria que começar do zero e aprender outra linguagem, nao sei se teria tempo pra isso, mas é uma otima ideia GIL.....

Outra opção é fazer programa multitarefa em tempo real (usando o RT-Linux) e criar uma Task ou uma Thread em assembly,

GIl, meu programa funciona com sistema multitarefa Thread, uso dois Thread's e funciona em tempo real da pra definir a prioridade alta, media e baixa......


Em resumo, se queres mais velocidade, tem que ir além... usar assembly, dominar a máquina, o sistema operacional...

Nos que começamos a programar em uma linguagem as vezes pensamos que vai ser facil, "dominar a maquina" é um assunto que realmente ainda não faz parte da minha realidade de programador hobysta....preciso de ajuda.....

VOU POSTAR EM SEGUIDA O MEU PROGRAMA, COMO FICOU A INTERFACE ETC, pode ser que assim fique mais facil obter uma ajuda de como fazer esse motor a passo rodar na mesma velocidade de um programa CNC.



[/quote]
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 03 de Outubro de 2009, 13:46
Odail,

Olhe a função a seguir:

int comanda_motor( void )
{
   outport(0x378, 2); // pino 2 da porta paralela em nivel "1"
   // sleep(10) causa atraso de 10 ms
   outport(0x378, 0); // pino 2 da porta paralela em nivel "0"
   // sleep(10) causa atraso de 10 ms
}

E agora olha essas duas instruções de setar bits da porta de um PIC:

bsf PORTB,2
bcf PORTB,2

Assumindo que antes de cada programa o nível de cada bit era zero, os dois programas ajustam um bit de uma porta no nível 1 e depois no nível zero. Pergunto, qual a duração (largura) do pulso nível 1? Como voce pode determiná-la?

A largura do pulso não é zero...

Qual a diferença entre os dois programas? Qual deve gerar o pulso de menor duração?
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 03 de Outubro de 2009, 15:41
Odail,

Olhe a função a seguir:

int comanda_motor( void )
{
   outport(0x378, 2); // pino 2 da porta paralela em nivel "1"
   // sleep(10) causa atraso de 10 ms
   outport(0x378, 0); // pino 2 da porta paralela em nivel "0"
   // sleep(10) causa atraso de 10 ms
}


Perfeito amigo GIL na minha linguagem C++ as linhas de programa acima para acessar o pino 2 da porta paralela estao corretissimas.....

E agora olha essas duas instruções de setar bits da porta de um PIC:

bsf PORTB,2
bcf PORTB,2


Muito massa isso amigo realmente o que esta me passando é algo novo, é assembly correto? em meu compilador pra pic ele ficaria assim:

output_high_PIN2;
output_low_PIN2;

Assumindo que antes de cada programa o nível de cada bit era zero, os dois programas ajustam um bit de uma porta no nível 1 e depois no nível zero. Pergunto, qual a duração (largura) do pulso nível 1? Como voce pode determiná-la?
A largura do pulso não é zero...


Agora sim, estamos chegando a um entendimento, realmente GIL parece que o meu programa so esta determinando a "FREQUENCIA" correto? porque ms (milisegundos) determina a frequencia e não a largura dos dos pulsos correto?

pode ser o erro do meu raciocinio que esta acarretando em um desempenho de baixa rotação do motor...eu nao tenho OSCILOSCOPIO AQUI para determinar a largura dos Lpulsos que saem do meu programa, dou um outro palpite abaixo:

  outport(0x378, 2);
  sleep(35) //causa atraso de 30 ms SENDO ASSIM o nivel alto (ligado) fica por ativo   por mais tempo
  outport(0x378, 0);
  sleep(5) // causa atraso de 5 ms, da mesma forma o sinal de clock fica em nivel baixo (desligado) por menos tempo. uma ilustração abaixo: é mais ou menos assim que esta no datashet do L297..
     ____   ____
    |      | |     |
    |      | |     |


Qual a diferença entre os dois programas? Qual deve gerar o pulso de menor duração?


è justamente isso que queria saber como faço pra manter um pulso LARGO e outro e outro MENOS LARGO e ainda por cima ainda controlar a frequencia dos mesmo no estado em que eles se encontram.......... ...



[/quote]
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 03 de Outubro de 2009, 17:16
Odail,

Para voce gerar uma onda retangular como a figura abaixo. A frequência, em Hertz, é dada por:

f = 1 / (Toff+Ton)

Sendo os tempos em segundos.

O trecho de programa para gerar uma onda retangular seria conforme a seguir:

    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          sleep(Ton);             //  Duração do nível "1"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
          sleep(Toff);            //  Duração do nível "0"
    }

Observe o seguinte:
(1) A duração do nível "0" é o tempo necessário para executar as instruções "sleep(Toff) e o while". Atente que, para pequenos valores de Toff (um ou dois milissegundos), o tempo necessário para executar o while pode ser significativo. Mas isso depende do compilador (por isso assembly é melhor, voce não fica imaginando coisas), ou então usa um osciloscópio ou frequencimetro, pelo menos.

(2) Se voce ligar um frequencímetro no pino 2 poderá determinar f. Voce não consegue um multímetro com frequencímetro?
 
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 03 de Outubro de 2009, 18:35
O trecho de programa para gerar uma onda retangular seria conforme a seguir:

    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          sleep(Ton);             //  Duração do nível "1"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
          sleep(Toff);            //  Duração do nível "0"
    }


Caro Gil, com base no codigo acima que parametros você usaria (linhas de programa) pra gerar um sinal de clock  com frequencia de 5000 hz?

andei fazendo uns testes tipo assim:

se 10ms é igual ou aproximadamente 100 hz, entao 1ms seria = a 1000 hz, nesse caso so conseguiria no máximo 1khz usando o codigo C++ com o comando sleep(), se for assim meu projeto ta perdido?

Observe o seguinte:
(1) A duração do nível "0" é o tempo necessário para executar as instruções "sleep(Toff) e o while". Atente que, para pequenos valores de Toff (um ou dois milissegundos), o tempo necessário para executar o while pode ser significativo. Mas isso depende do compilador (por isso assembly é melhor, voce não fica imaginando coisas), ou então usa um osciloscópio ou frequencimetro, pelo menos.


entendi pefeitamente o que quis dizer amigo.......

(2) Se voce ligar um frequencímetro no pino 2 poderá determinar f. Voce não consegue um multímetro com frequencímetro?

Dei uma olhada no meu multiteste e ele tem frequencimetro sim, vou tentar medir e posto aqui....

[/quote]
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 03 de Outubro de 2009, 19:23
O trecho de programa para gerar uma onda retangular seria conforme a seguir:

    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          sleep(Ton);             //  Duração do nível "1"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
          sleep(Toff);            //  Duração do nível "0"
    }


Caro Gil, com base no codigo acima que parametros você usaria (linhas de programa) pra gerar um sinal de clock  com frequencia de 5000 hz?

Para 5000 Hz, período será de 0,2 ms, e deveria usar a seguinte rotina:

    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          sleep(0.1);             //  Duração do nível "1"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
          sleep(0.1);            //  Duração do nível "0"
    }


Masssss, fica a pergunta, o sleep do C++ poderia ser menor do que 1 ou então 0.1?

Se o valor mínimo for 1, então a frequência máxima obtida com esse comando no C++ é de 500 Hz, pois são 1ms no nível 1 e 1 ms no nível 0.

Esse comando sleep não é padronizado, há compiladores em que o valor é em segundos, aceitando-se valores menores do que um.

se 10ms é igual ou aproximadamente 100 hz, entao 1ms seria = a 1000 hz, nesse caso so conseguiria no máximo 1khz usando o codigo C++ com o comando sleep(), se for assim meu projeto ta perdido?

Para sleep(1), a frequência máxima é de 500Hz, conforme expliquei acima..

Se o seu projeto está perdido eu não sei  :)

Pois ainda há várias opções: usar assembly, não usar o sleep, usar outra linguagem......

Dei uma olhada no meu multiteste e ele tem frequencimetro sim, vou tentar medir e posto aqui....

Há uma luz no fim do túnel...  :)

Voce poderia testar qual a frequencia que esse programa abaixo gera em teu sistema:

    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
    }

Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 03 de Outubro de 2009, 20:53
Citar
Para 5000 Hz, período será de 0,2 ms, e deveria usar a seguinte rotina:

    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          sleep(0.1);             //  Duração do nível "1"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
          sleep(0.1);            //  Duração do nível "0"
    }


Amigão Gil eu estou torcendo para que o C++ BUILDER aceite sleep menor do que 1ms, vou chegar em casa hoje e ja vou direto testar.......

Citar
Se o valor mínimo for 1, então a frequência máxima obtida com esse comando no C++ é de 500 Hz, pois são 1ms no nível 1 e 1 ms no nível 0.


Sinceramente uma frequencia muito pequena pra rodar um motor a passo que tem um clock como tipo de acionamento......na o sei muito bem como calcula isso pra rodar o motor a passo..seria dividir as especificações do motor pela frequencia? deve haver um calculo :-\

Citar
Esse comando sleep não é padronizado, há compiladores em que o valor é em segundos, aceitando-se valores menores do que um.


Isso é verdade Gil, observando aqui na internet achei ate comando de tempo  como por exemplo "usleep" e disseram no forum que era pra frequencias abaixo de 1ms ou seja, microsegundos..

Citar
Se o seu projeto está perdido eu não sei  :)

Caro amigo Gil, so ainda não estou perdido porque pessoas como você não desistem de mim :D senão talvez ja teria apagado todo o meu codigo e desistido de tudo.
parabens por ser assim.

Citar
Pois ainda há várias opções: usar assembly, não usar o sleep, usar outra linguagem......

So apenas ainda nao usei o PIC 16F877A para esse projeto que inclusive tem comando de tempo abaixo de 1ms, porque eu preciso de uma interface pra operar os sistema o C++ BUILDER é um "animal" nisso muito bom mesmo.

Voce poderia testar qual a frequencia que esse programa abaixo gera em teu sistema:

Citar
    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
    }

posso sim amigo, so não faço agora porque simplesmente meus equips de eletronica estão em casa..mas nao perde por esperar.. ja estou correndo pra casa pra efetuar todos esses testes e posto em seguida....abração.
[/quote]
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 04 de Outubro de 2009, 13:17
Citar
Voce poderia testar qual a frequencia que esse programa abaixo gera em teu sistema:

Citar
    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
    }

Caro amigo, eu testei as linhas de programa acima  e nao acontece nada, nao existe nenhum sinal de clock na entrada.

Depois disso eu adicionei um Sleep com uma atraso de 1ms e testei com o frequencimentro do meu multimetro e tive uma grande surpresa!!! tava dando 035 hz, isso ja com com o menor atraso que é de 1ms, impressionante como esta baixa a frequencia, desse jeito o motor nao roda rapido de jeito nenhum....

depois eu abri o kcam  e testei o eixo "Y" e a velocidade do motor foi estarrecedoramente alta, sendo assim resolvi testar a frequencia que o KCAM e estava mandando para o L297, outra surpresa!!! estava dando 435 hz, ou seja 12,5X a mais do que o meu programa, com isso cheguei  a conclusao que preciso mudar a forma de gerar o clock que quero

mas em tese o comando sleep nao era pra da so 35hz com os parametros que usei.....agora encucou tudo...
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 04 de Outubro de 2009, 13:39
Citar
    while(1)
    {
          outport(0x378, 0x2); // Setar pino 2 da porta paralela em nivel "1" e o resto em "0"
          outport(0x378, 0);   //  Setar todos os pinos da paralela para "0")
    }

Caro amigo, eu testei as linhas de programa acima  e nao acontece nada, nao existe nenhum sinal de clock na entrada.

Eu não afirmaria isso categoricamente, já fiz programa desse tipo em DOS e algo deveria ser gerado. Mas também não vou afirmar que voce está errado. A verdade.... só com um osciloscópio.

As coisas não são tão simples assim....

Depois disso eu adicionei um Sleep com uma atraso de 1ms e testei com o frequencimentro do meu multimetro e tive uma grande surpresa!!! tava dando 035 hz, isso ja com com o menor atraso que é de 1ms, impressionante como esta baixa a frequencia, desse jeito o motor nao roda rapido de jeito nenhum....

depois eu abri o kcam  e testei o eixo "Y" e a velocidade do motor foi estarrecedoramente alta, sendo assim resolvi testar a frequencia que o KCAM e estava mandando para o L297, outra surpresa!!! estava dando 435 hz, ou seja 12,5X a mais do que o meu programa, com isso cheguei  a conclusao que preciso mudar a forma de gerar o clock que quero

mas em tese o comando sleep nao era pra da so 35hz com os parametros que usei.....agora encucou tudo...

O problema é o velho e bom Windows. Programação em tempo real com Windows é coisa "cabeluda" mesmo... É por isso que os desenvolvedores de programas desse tipo usam o DOS ou o Linux (que permitem acessar o hardware diretamente, tendo controle total do PC.
 
Para usar o Windows, tem que fazer alguns truques "sujos"...

Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 05 de Outubro de 2009, 20:28
Citar
O problema é o velho e bom Windows. Programação em tempo real com Windows é coisa "cabeluda" mesmo... É por isso que os desenvolvedores de programas desse tipo usam o DOS ou o Linux (que permitem acessar o hardware diretamente, tendo controle total do PC.

Eu gosto muito do C++ BUILDER amigo, acho que por ser uma ferramenta de programação dedicada a interface fica devendo algumas outras coisas como por exemplo esse problema que estou enfrentando.
Qual programa outra plataforma você me indicaria pra terminar meu projeto} delphi?

Bem vindo à "selva"... 

OOOPPPPAAAA!!!! é nessa selva que eu estou ja quase morrendo, vou ter que ver como faço pra sobreviver
 
Citar
Para usar o Windows, tem que fazer alguns truques "sujos"...

Pelo meu modo de ver o tio bill gates se encarregou de deixar a nossa vida muito pior na versao do winxp....
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 06 de Outubro de 2009, 04:37
Eu gosto muito do C++ BUILDER amigo, acho que por ser uma ferramenta de programação dedicada a interface fica devendo algumas outras coisas como por exemplo esse problema que estou enfrentando.
Qual programa outra plataforma você me indicaria pra terminar meu projeto} delphi?

Pois é, o Windows foi feito basicamente para ser uma grande interface gráfica.... Acredito que o C++ Builder vai um pouco nessa linha. O Builder também possui funções de gerenciamento de arquivos, redes, imagem, som, ... mas tempo real mesmo é uma outra história. Aplicações de tempo real requerem mais controle do PC (para garantir a temporização) e isso é uma coisa na contramão do que o Windows faz, que é também ter controle da máquina, mas dentro desse contexto de interface gráfica.

Tirei esse trecho da página da Microsoft (http://support.microsoft.com/kb/22523):

Windows não oferece suporte a programação em tempo real

Em nenhum sentido pode Microsoft Windows ser considerada um sistema "em tempo real". Ele é um sistema orientado a mensagem, pesquisa de evento, com o agendamento nonpreemptive.

O Windows é um sistema que essencialmente baseia-se em eventos do tipo: cliques e rolagem do mouse, acionamento do teclado, ....), ou seja, interface com o usuário. Já sistemas de tempo real precisam atender a restrições de tempo de resposta, eventos periódicos, baixo tempo de latência, priorização de interrupções, preempção, ....

Já fiz alguns programas em VB 3.0 em Windows 3.11, que efetuavam controle do tipo PID (proporcional, integral, derivativo) em malha fechada (bons tempos...) acho que o mais rápido era 100 ou 200 ms. Acho que isso só era possível porque, essas primeiras versões de Windows eram "cascas gráficas" em cima do DOS.

Bem vindo à "selva"... 

OOOPPPPAAAA!!!! é nessa selva que eu estou ja quase morrendo, vou ter que ver como faço pra sobreviver
 
Citar
Para usar o Windows, tem que fazer alguns truques "sujos"...

Pelo meu modo de ver o tio bill gates se encarregou de deixar a nossa vida muito pior na versao do winxp....

Não acho que o Bill Gates esteja muito interessado no mercado de sistemas de tempo real (acredito que o mercado é relativamente pequeno face aos sistemas de multimídia, jogos, ...). Mas também não tenho experiência em programar em Windows nesse nível de milissegundos, para controlar um motor de passo. Aliás, acho que é uma tarefa hercúlea e que requer muitas ferramentas, compiladores e conhecimentos mais específicos. E também creio que o esforço para uma atividade de programação em tempo real, do tipo hobby, teria mais retorno usando o DOS (Ex.: FreeDOS) ou o Linux.

Uma outra abordagem é tratar o Windows naquilo que é mais indicado, que é ser uma boa interface com o usuário e acoplar a esse sistema um outro processador (PIC, PC) para as aplicações de baixo nível e de baixo tempo de resposta. Nesse sistema poderia ser empregado DOS, LINUX ou nenhum sistema operacional.
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 06 de Outubro de 2009, 07:37
Bom dia,

uma alternativa é vc tentar usar as API's: "QueryPerformanceCou nter" e "QueryPerformanceFre quency". tem uma precisão de nanosegundos.

vai ocorrer atrasos na temporização por causa do windows. mas é uma base de tempo.

Artigo MSDN: How To: Time Managed Code Using QueryPerformanceCou nter and QueryPerformanceFre quency we can see result in nanoseconds
http://msdn.microsoft.com/en-us/library/ms979201.aspx (http://msdn.microsoft.com/en-us/library/ms979201.aspx)
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 06 de Outubro de 2009, 08:16
Cláudio,

Bom dia, ao usar essas funções, o Windows poderá ajudar na medição do desempenho (velocidade) de execução do programa. A questão é como executar o programa com velocidade usando o / ou dentro do Windows...

Do mesmo modo, o Windows não deveria  alterar a frequência de envio da sequência de pulsos do programa, para acionar o driver dos motores de passo, seja afetada. Essa frequência pode ser da ordem de 10.000Hz. Não sei se isso poderia ser garantido dentro do Windows (talvez no Windows 2000 ou NT??)...

Um outro aspecto é que, de um modo geral, a linguagem C++ pode ser poderosa para fazer interfaces gráficas, mas não é eficiente para programação em tempo real, vejam o artigo: http://www.research.att.com/~bs/esc99.html

Eu particularmente prefiro o assembly ou no máximo o ANSI C ou algo parecido.  Principalmente para poder gerar sinais da ordem de KHz via software.

Existem dois mundos que possuem requisitos conflitantes, que são a interface com o usuário, que deve ser gráfica, funcional,.... e o lado "máquina" do software, que deve se comportar como um relógio, com resolução de microssegundos e sem atrasar ou adiantar nada. Uma linguagem ideal deveria atender tudo isso (difícil, talvez só o assembly, mas vá tentar montar uma interface gráfica com assembly...), ou então usar dois sistemas interdependentes.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 06 de Outubro de 2009, 10:22
Professor Gil, muito obrigado pelas informações, estou aprendendo muito com você, so tenho a agradecer.....

Citar
para as aplicações de baixo nível e de baixo tempo de resposta. Nesse sistema poderia ser empregado DOS, LINUX ou nenhum sistema operacional.

Em tempo real uso threads que é a melhor forma de usar o windows em tempo real, acredito que outros programadores usem alguns "truques sujos" como você comentou...mas tambem usem Threads,

Algumas considerações (ou opções) que me deixam confuso...

1 - digamos que eu mude de SO para linux, como posso compatibilizar esse software com um amigo que nao usa linux e sim windows?

2 - os programadores tem formas de converter isso? passo a acreditar que mesmo usando outro SO o codigo gerado seria pra windows pois um arquivo .EXE que roda no linux roda em windows pelo fato de ser .EXE?

2 - O você acha de usar um pic 16F877A e esquecer a interface por enquanto? a programação seria bem mais simples mas roubaria a "magia" de controlar tudo por PC..

3 - A porta USB é muito mais rapida e seria uma opção interessante e moderna pra mim, parece que o BILL fornece suporte para essa porta trabalhar em tempo real, falo isso porque a Rogercom tem otimos curso pela net.

4 - Existem softwares geradores de CLOCK na internet que geram onda quadrada 1 a 20 khz, precisaria de um codigo aberto de uma programa desses (e ja estou atras) pra saber quais "truques" os programdores usaram para enganar o o nosso (R)windows.....


Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 06 de Outubro de 2009, 11:02
Em tempo real uso threads que é a melhor forma de usar o windows em tempo real, acredito que outros programadores usem alguns "truques sujos" como você comentou...mas tambem usem Threads,

Algumas considerações (ou opções) que me deixam confuso...

1 - digamos que eu mude de SO para linux, como posso compatibilizar esse software com um amigo que nao usa linux e sim windows?

2 - os programadores tem formas de converter isso? passo a acreditar que mesmo usando outro SO o codigo gerado seria pra windows pois um arquivo .EXE que roda no linux roda em windows pelo fato de ser .EXE?

2 - O você acha de usar um pic 16F877A e esquecer a interface por enquanto? a programação seria bem mais simples mas roubaria a "magia" de controlar tudo por PC..

3 - A porta USB é muito mais rapida e seria uma opção interessante e moderna pra mim, parece que o BILL fornece suporte para essa porta trabalhar em tempo real, falo isso porque a Rogercom tem otimos curso pela net.

4 - Existem softwares geradores de CLOCK na internet que geram onda quadrada 1 a 20 khz, precisaria de um codigo aberto de uma programa desses (e ja estou atras) pra saber quais "truques" os programdores usaram para enganar o o nosso (R)windows.....

1 - Não sei..., é complicado rodar algo em tempo real (de verdade) usando um simulador de Linux dentro do Windows ou algo similar. A tecnolgia ainda não chegou a esse ponto...

2 - Seria uma boa opçao, mas o "pulo do  gato" é saber como cortar as tarefas, ou seja, o que fica no PC e o que vai para o PIC. De modo a balancear: velocidade de resposta, carga de processamento, tipo de processamento, .... A interface "bonitinha" poderia ser feita depois.
 
3 -Cuidado com a USB, existem vários modos de operação, alguns são como uma porta serial embutida (no maximo 115 kbps). Mas a questão não é tanto a velocidade da porta, mas o balanceamento da carga de processamento, pois a parte rápida não ficaria no PC. Excetuando os sistemas de multimídia, uma interface USB rápida não foi pensada em sistemas de controle em tempo real, mas, sendo rápida, acelera a transferência de um arquivo, mas para controle direto dos motores, esse fluxo deve ser constante e sem variações de frequência, o que, novamente esbarra na limitação do software dentro do PC.

4 - Eu acredito que esse geradores usam a saída de áudio do PC, que não possui nível de sinal TTL para acionar motores!! Para isso o Windows possui algumas coisas específicas. Mas quem gera o sinal não é uma "porta paralela", mas um conversor D/A da placa de áudio, que também possui um buffer (memória), para absorver o jitter e atrasos no envio de dados. Algo semelhante a um CD player a prova de buracos na estrada, ou seja, voce toca o CD mas não é interrompido se a cabeça de leitura se afastar do CD por alguns momentos. A estrada esburacada seria o (R)Windows...  :)

Mas ai teria que usar um placa de som com tres canais de áudio sincronizados a nível de cada bit, acho que seria complicado....

Existem processadores DSP (dsPIC), que são rápidos e acho que poderiam ajudar nesse tipo problema, fora do PC.... Ou dentro (uma placa dedicada).
Título: Re: CLOCK em microsegundos
Enviado por: C N C N o w ! em 06 de Outubro de 2009, 12:10
4 - Existem softwares geradores de CLOCK na internet que geram onda quadrada 1 a 20 khz, precisaria de um codigo aberto de uma programa desses (e ja estou atras) pra saber quais "truques" os programdores usaram para enganar o o nosso (R)windows.....

Não há truques e não são necessários, o SO atribui elevada prioridade às tarefas concernentes ao codec de áudio por motivos óbvios.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 06 de Outubro de 2009, 18:18
Citar
Não há truques e não são necessários, o SO atribui elevada prioridade às tarefas concernentes ao codec de áudio por motivos óbvios.

Ah bem lembrado isso amigo, eu tenho no meu programa como da prioridade ao processamento em tempo real em:

- PRIORIDADE NORMAL
- PRIORIDADE MEDIA
- PRIORIDADE ALTA

com apenas mais algumas linhas eu poderia trabalhar em prioridade "ALTA" sera que isso mudaria alguma coisa no meu programa?


Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 06 de Outubro de 2009, 18:29
Citar
2 - Seria uma boa opçao, mas o "pulo do  gato" é saber como cortar as tarefas, ou seja, o que fica no PC e o que vai para o PIC. De modo a balancear: velocidade de resposta, carga de processamento, tipo de processamento, .... A interface "bonitinha" poderia ser feita depois.

Gil eu falei em abandonar totalmente qualquer tipo de interface deixando o meu projeto um pouco sem graça caso eu migre pro PIC, pelo que andei pesquisando acessar o PIC por PC não é muito legal, se fosse fazer isso partiria logo pra USB que é mais moderno.

No caso do PIC você acha que eu poderia conseguir velocidade em MICROSEGUNDOS?


 
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 06 de Outubro de 2009, 19:20
Gil eu falei em abandonar totalmente qualquer tipo de interface deixando o meu projeto um pouco sem graça caso eu migre pro PIC, pelo que andei pesquisando acessar o PIC por PC não é muito legal, se fosse fazer isso partiria logo pra USB que é mais moderno.

O PIC poderia ser acessado via interface serial (RS232 ou RS485) ou USB.


No caso do PIC você acha que eu poderia conseguir velocidade em MICROSEGUNDOS?

Voce quer dizer tempo de execução de instrução de 1 us, não é? Com 20MHz, cada instrução de máquina é executada em 200 ns. Há modelos, com interface USB, que podem trabalhar acima de 40Mhz.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 06 de Outubro de 2009, 19:52
Citar
Voce quer dizer tempo de execução de instrução de 1 us, não é? Com 20MHz, cada instrução de máquina é executada em 200 ns. Há modelos, com interface USB, que podem trabalhar acima de 40Mhz.

Entendi a resposta como um "SIM" e ja estou corroendo a placa de circuito impresso em acido para criar um pequeno laboratorio com o PIC 16F877A-20 (que trabalha com 20MHZ) com todos os seus IN/OUT's separados e vou começar a fazer testes com PIC.

Ja pra comunicação via porta seria RS232 não tenho nem noção de como vou começar , sei que usa o C.I. max232 para comunicar-se com o PC, agora correr atras de codigos de comunicação nas comunidades por ai...

MUITO OBRIGADO por me orientar, so gostaria muito de poder ainda um dia realizar esse projeto via porta paralela, se conseguir posto nesse mesmo topico.

ABRAÇÃO.
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 07 de Outubro de 2009, 08:17
Bom dia,

Bom dia, ao usar essas funções, o Windows poderá ajudar na medição do desempenho (velocidade) de execução do programa. A questão é como executar o programa com velocidade usando o / ou dentro do Windows...

Do mesmo modo, o Windows não deveria  alterar a frequência de envio da sequência de pulsos do programa, para acionar o driver dos motores de passo, seja afetada. Essa frequência pode ser da ordem de 10.000Hz. Não sei se isso poderia ser garantido dentro do Windows (talvez no Windows 2000 ou NT??)...

Com a base de tempo, um pouco de criatividade e com um bom computador, acredito sim que seja possível chegar prox aos 10khz. (Já fui feliz empregando em algo parecido... mas n tao exigido.)

Citar
Um outro aspecto é que, de um modo geral, a linguagem C++ pode ser poderosa para fazer interfaces gráficas, mas não é eficiente para programação em tempo real, vejam o artigo: http://www.research.att.com/~bs/esc99.html

concordo em gênero, número e grau... O Artigo do msdn que eu postei, é em cima do .Net, mas n impede de que seja utilizando C Win32. mesmo pq fazer programas rápidos através de framework... só com mágica.
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 07 de Outubro de 2009, 09:26
Cláudio,

Citar

Com a base de tempo, um pouco de criatividade e com um bom computador, acredito sim que seja possível chegar prox aos 10khz. (Já fui feliz empregando em algo parecido... mas n tao exigido.)


Pois é, os motores de passo numa CNC trabalham com 15 Khz ou mais, portanto, acho que fui modesto....

Para trabalhar (direito) devem haver folgas, acredito que o programa deveria poder chegar sem esforços nos 50kHz, num PC considerado médio, usando o MS-Windows (qual?) e um programa em C padrão (ex.: ANSI) - compilador C (qual?).

Outras opções (resultados garantidos em menos tempo, menor esforço):
- Partir totalmente para arquitetura mais aberta (PC, Linux)
- Partir para uma arquitetura híbrida, com mais controle da "situação" (PC ,Windows, C++, PIC, Assembly PIC). 
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 07 de Outubro de 2009, 11:21
Citar
Com a base de tempo, um pouco de criatividade e com um bom computador, acredito sim que seja possível chegar prox aos 10khz. (Já fui feliz empregando em algo parecido... mas n tao exigido.)


caro amigo, como coseguiu tal facanha? tem algum esboço de codigo de como conseguiu? porque no maximo que consegui foi 60hz >:(

se eu conseuisse pelo menos 1000hz ja estaria feliz.... ;D

os caras que programao em CNC sabem como fazer mas nao conhecço nenhum que de pelo menos uma dica (veja que nao quero codigo pronto) so uma luz.......
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 07 de Outubro de 2009, 22:10
Boa noite,

minilathe,

acho q fui mal compreendido... eu n estou aqui defendendo o windows e mto menos sugerindo que se faça algum programa sério e confiável com base nos meus palpites. minha intenção foi só de ajudar o colega matrixlan. pois pelo q pude intender, ele n estava precisando de nd mto sofisticado.



matrixlan,

assim q eu tiver o código em mãos, eu posto aqui para ver se te ajuda.


Sds.
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 07 de Outubro de 2009, 23:08
Claudio,


minilathe,

acho q fui mal compreendido... eu n estou aqui defendendo o windows e mto menos sugerindo que se faça algum programa sério e confiável com base nos meus palpites. minha intenção foi só de ajudar o colega matrixlan. pois pelo q pude intender, ele n estava precisando de nd mto sofisticado.

Ok, sem stress.... não sou sócio do Bill Gates nem concorrente direto. E se voce tiver algum programa que rode rápido no Windows, conforme temos discutido aqui, será bem vindo...

Contra fatos, não há argumentos....  :)
Título: Re: CLOCK em microsegundos
Enviado por: C N C N o w ! em 08 de Outubro de 2009, 07:06
E se voce tiver algum programa que rode rápido no Windows, conforme temos discutido aqui, será bem vindo...

Acho que é importante enfatizar que o prob com o Win não é - e nunca foi - a velocidade, muito menos na atualidade, com máquinas muito rápidas e baratas ao alcance de todos.

O prob é - e sempre foi - a latência, causada pelas interrupções do SO, portanto os masoquistas que pretendem se aventurar nesse pântano devem começar por estudar maneiras de evitar a interferência das tarefas de housekeeping, o resto é relativamente trivial e está ao alcance de muitos programadores.

Merece reflexão o fato de o mais bem sucedido prog pra Win, o Mach, ser em parte um port do EMC e empregar um driver pra lidar com a coisa. Quer me parecer que o Art Fenerty aproveitou o monumental trabalho relativo à cinemática do EMC e tratou de concentrar-se nas questões relativas à administração das prioridades ...

Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 08 de Outubro de 2009, 18:29
Citar
minha intenção foi só de ajudar o colega matrixlan. pois pelo q pude intender, ele n estava precisando de nd mto sofisticado.

Realmente amigo, meu programa não tem sofisticação nenhuma, apenas um MÍSERO SINAL DE CLOCK (desculpem se foi rude) oscilando numa frequencia de até 1000hz ou mais, para acionar qualquer eixo da CNC3AX que eu quisesse

ja tenho o codigo em C++ BUILDER que faz isso com o pino 2 da porta paralela so que dá no máximo 40hz, isso é muito pouco para um padrão de atraso de 1ms que estou usando para rampa ALTA e rampa BAIXA em "loop".. deveria da pelo menos 400hz(?)

mas enfim o nosso amigo GIL ja meu deu muitas explicação de o porquê que não consigo isso e cada vez nos convencemos mais que o (R)windows é o maior vilão.

Citar
matrixlan,

assim q eu tiver o código em mãos, eu posto aqui para ver se te ajuda.

Opa amigo, será sempre bem vindo e será sempre uma grande ajuda, como eu disse "não estou me aproveitando dos colegas pra pegar cõdigos prontos" apenas os meu conhecimentos congelaram... ;)

Abraço.
[/quote]
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 08 de Outubro de 2009, 18:44
Citar
O prob é - e sempre foi - a latência, causada pelas interrupções do SO, portanto os masoquistas que pretendem se aventurar nesse pântano devem começar por estudar maneiras de evitar a interferência das tarefas de housekeeping, o resto é relativamente trivial e está ao alcance de muitos programadores.


kkkkk...gostei do masoquista foi bem exótico isso, de latencia em conheço um pouco e sei que atrasos de 10ms ou menor ja fazem um terrorismo grande num sistema, por isso amigo que eu uso Threads com base de tempo real no meu programa, sinceramente eu uso dois Threads em "prioridade maxima" ou seja: quase toda força do sistema é dedicada ao programa evitando justamente problemas com latências, se elas acontecem é num espaço de tempo desconhecido pelas linhas do proprio programa, uma traição ao código numa linguagem mais rude....

Agora eu fiquei curioso onde acontece essas interrupções de SO? em que momento isso acontece..quando executo meu programa?
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 08 de Outubro de 2009, 19:22
Oldair,

kkkkk...gostei do masoquista foi bem exótico isso, de latencia em conheço um pouco e sei que atrasos de 10ms ou menor ja fazem um terrorismo grande num sistema, por isso amigo que eu uso Threads com base de tempo real no meu programa, sinceramente eu uso dois Threads em "prioridade maxima" ou seja: quase toda força do sistema é dedicada ao programa evitando justamente problemas com latências, se elas acontecem é num espaço de tempo desconhecido pelas linhas do proprio programa, uma traição ao código numa linguagem mais rude....

Agora eu fiquei curioso onde acontece essas interrupções de SO? em que momento isso acontece..quando executo meu programa?

Conselho..., não confie cegamente nas Threads que o Windows disponibiliza.

Já fiz programas multiprocessos e multithreads (são duas coisas diferentes) em VMS, LINUX e SUN-OS, verdadeiros S.O. multitarefa e multiusuário. Não sou profundo conhecedor do Windows, mas sei que na família Windows, excetuando o Windows NT, que era cópia do VMS, geralmente não são verdadeiramente multitarefa. O VMS era um S.O. famoso da finada DEC (Digital Equipment Corporation), ou "Digital" para os íntimos.

Um pouco de história: A DEC era concorrente da IBM em sistemas de processamento científico e de universidades. Os equipamentos da DEC e o VMS junto com os UNIX, foram um dos fundamentos no desenvolvimento da Rede Ethernet e da Internet....
 
A contrução de threads existe em qualquer S.O. decente. Threads são pequenos processos que o sistema operacional permite criar dentro do contexto do seu programa, simulando um sistema multitarefas.

Desse modo, em determinados momentos (deveria ser periodicamente, com desvio de microsegundos ou menos em sistemas de tempo real), o Windows passa o controle da CPU para uma das Threads, permitindo que a mesma seja executada. Como o Windows não é um sistema de tempo real, a temporização de execução dessas threads não é determinística, ou seja, as threads não são executadas dentro de um escalonamento de tempo previsível. Altamente desejável em sistemas de controle, acionamentos de máquinas, motores, etc...

Além disso, o fato de voce poder ajustar uma "prioridade" de uma Thread não é a solução definitiva, pois lembre-se que o Windows ainda está no (des)controle de tudo, conforme critérios obscuros e ocultos à maioria dos "mortais". A prioridade permite ao Windows decidir quando houverem duas ou mais Threads na fila para serem executadas, ou que receberem uma interrupção (teclado, mouse, porta serial, disco, rede...), qual será executada primeiro, segundo, terceiro,.... Mas perceba, que só isso não garante a periodicidade de tempo invariável na execução. Seria necessário um escalonador de tempo real, um sistema reentrante para tratamento de interrupções com baixa latência, ...... Coisas que, até onde eu sei, o Windows não possui...
Título: Re: CLOCK em microsegundos
Enviado por: marc0 em 08 de Outubro de 2009, 20:37
Algumas considerações.

Não sei porque tanta aversão ao Windows; eu uso o XP a muitos anos e estou plenamente satisfeito com ele. não me parece legal esse negócio de jogar pedras. Acho o Linux muito bom e que atende os objetivos dos seus usuários, assim com o Win atende a grande maioria que o usa.

Todo SO é programado visando certos objetivos, certamente os objetivos da MS contempla uma estratégia de funcionalidade que visa auferir lucros com a venda, nenhum SO vai ser o melhor em tudo, e certamente a latência do Win pode deixar a desejar para um uso não previsto. 

"Cada sistema utiliza uns milésimos de segundos para gerenciar estes intervalos de tempo. Assim um sistema gasta 1/n segundos por intervalo; algo como 1/33 para o W95, 1/100 para a série o Windows NT, 1/250 para o Linux padrão e 1/1000 para o Linux com Kernel RT"  (fonte : http://flavioschiavoni.blogspot.com/2008/08/o-que-kernel-rt.html )

Nem tudo são flores e certamente existe alguns podres no reino da Dinamarca e como toda empresa a MS tem os seus pecados, nem sempre acerta em tudo, mas o sucesso que alcançou num ramo tão competitivo como esse de "software" deixando muitos concorrentes peso pesado pelo caminho, indica que a maioria dos seus produtos são tudo, menos ruins.

Por razões obvias muitas partes do WIN não são de conhecimento geral, claro se houvesse maiores detalhes facilitaria interações e uma maior compatibilidade; o desconhecimento pode acarretar bugs e travamentos de soft incompatíveis.

Não considero programar algo que funcione à contento em condições adversas seja um truque sujo, mas sim a perspicácia de conhecer as possibilidades e retirar delas os melhores benefícios. Taí o mérito do Mach, Kcam e companhia.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 08 de Outubro de 2009, 20:42
Citar
Além disso, o fato de voce poder ajustar uma "prioridade" de uma Thread não é a solução definitiva, pois lembre-se que o Windows ainda está no (des)controle de tudo, conforme critérios obscuros e ocultos à maioria dos "mortais".


É verdade mesmo professor GIL, se a prioridade resolvesse isso de verdade meu programa estaria funcionando a uns 500hz

mas olha o que eu achei pequisando na internet:

// Wait 0.2ms

procedure PerformanceDelay;
var
hrRes, hrT1, hrT2, dif: Int64;
begin
if QueryPerformanceFre quency(hrRes) then
begin
QueryPerformanceCou nter(hrT1);
repeat
QueryPerformanceCou nter(hrT2);
dif := (hrT2 - hrT1) * 10000000 div hrRes;
until dif > 2;
end;
end;

essas linhas de comando causam um atraso de 0.2ms e me parece ser escrito para DELPHI..você por acaso saberia decifrar alguma coisa?

Observando o codigo acima passo a observar que o nosso amigo Claudio S. tinha alguma razão quando falou de "QueryPerformanceCou nter" e "QueryPerformanceFre quency".
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 08 de Outubro de 2009, 23:29
Marco,

Não sei porque tanta aversão ao Windows; eu uso o XP a muitos anos e estou plenamente satisfeito com ele. não me parece legal esse negócio de jogar pedras. Acho o Linux muito bom e que atende os objetivos dos seus usuários, assim com o Win atende a grande maioria que o usa.

Todo SO é programado visando certos objetivos, certamente os objetivos da MS contempla uma estratégia de funcionalidade que visa auferir lucros com a venda, nenhum SO vai ser o melhor em tudo, e certamente a latência do Win pode deixar a desejar para um uso não previsto. 

Eu também uso o Windows (até comprei uma licença oficial), mas gosto de falar mal do Bill Gates....  ;D

Brincadeira....

O Windows é aceitável para o nosso feijão com arroz.

Mas para um programador de sistemas de tempo real, existem muitas arestas no Windows.

Mas, se formos avaliar os diversos aspectos, do ponto de vista de um desenvolvedor de sistemas. A escolha de um S.O. é algo complexo, pois depende de diversas questões: mercadológicas (o publico alvo), se cumpre os objetivos a serem alcançados, se atende ao quesito preço e custo do produto final, se é estável, ....

Estamos tratando de algo bem específico. Mas com certeza, há produtos prontos no mercado rodando em Windows (ex.: Mach), ainda há um chance para o Windows...  :)


"Cada sistema utiliza uns milésimos de segundos para gerenciar estes intervalos de tempo. Assim um sistema gasta 1/n segundos por intervalo; algo como 1/33 para o W95, 1/100 para a série o Windows NT, 1/250 para o Linux padrão e 1/1000 para o Linux com Kernel RT"  (fonte : http://flavioschiavoni.blogspot.com/2008/08/o-que-kernel-rt.html )

Não considero programar algo que funcione à contento em condições adversas seja um truque sujo, mas sim a perspicácia de conhecer as possibilidades e retirar delas os melhores benefícios. Taí o mérito do Mach, Kcam e companhia.

O problema não é só obter tempos pequenos no Windows ou outro S.O., é manter o intervalo de tempo constante entre os eventos (ex.: pulsos gerados para um motor), independentemente do "humor do Windows". É por isso que os sistemas CNC com Windows não podem rodar mais nada que não seja o software de CNC, tem que ser "o mais pelados possível". Tente usar um browser, ou fazer um downlod pesado, rodar um antivirus, rodar o Media Player com o Mach operando uma CNC....
 
Com certeza, os autores do Mach, Kcam, ... souberam driblar os obstáculos, do Windows. Mas acho que não deveria ser uma ciência oculta... No DOS esse tipo de aplicativo era muito mais aberto, barato e fácil de fazer...

É sabido que programar em baixo nível num S.O. é um assunto complexo, mas, também tenho a impressão que o pessoal da MS quer ficar sócio em tudo que roda e é produzido para Windows. É a velha história de criar as dificuldades para vender as soluções (ex.: compiladores, cursos, informações, livros, certificações...).
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 08 de Outubro de 2009, 23:49
Odail,

Citar
Além disso, o fato de voce poder ajustar uma "prioridade" de uma Thread não é a solução definitiva, pois lembre-se que o Windows ainda está no (des)controle de tudo, conforme critérios obscuros e ocultos à maioria dos "mortais".


É verdade mesmo professor GIL, se a prioridade resolvesse isso de verdade meu programa estaria funcionando a uns 500hz

mas olha o que eu achei pequisando na internet:

// Wait 0.2ms

procedure PerformanceDelay;
var
hrRes, hrT1, hrT2, dif: Int64;
begin
if QueryPerformanceFre quency(hrRes) then
begin
QueryPerformanceCou nter(hrT1);
repeat
QueryPerformanceCou nter(hrT2);
dif := (hrT2 - hrT1) * 10000000 div hrRes;
until dif > 2;
end;
end;

essas linhas de comando causam um atraso de 0.2ms e me parece ser escrito para DELPHI..você por acaso saberia decifrar alguma coisa?

Observando o codigo acima passo a observar que o nosso amigo Claudio S. tinha alguma razão quando falou de "QueryPerformanceCou nter" e "QueryPerformanceFre quency".

Não sou muito íntimo do Delphi, mas posso te dizer que, geralmente, olhando um código em linguagem de alto nível é difícil dizer se roda mais rápido que outro código em outras linguagem. Isso depende do compilador, o quão eficiente na geração do código de máquina, a velocidade absoluta mesmo, só com assembly.

O programa que estamos discutindo pode ser temporizado como a seguir:

while(1) {
    outportb(0x378,0xFF);
    a = 10;
    outportb(0x378,0xFD);
    a = 10;


A linha a=10 é apenas para gastar tempo (similar a um sleep, de x milisegundos, onde x=??), voce pode medir a velocidade com um frequencímetro, mas ainda teremos o problema da latência variável do Windows...
Título: Re: CLOCK em microsegundos
Enviado por: marc0 em 08 de Outubro de 2009, 23:53
Olá Gil;

Obrigado por entender o ponto.
Gostei muito da sua réplica, inclusive concordo com a sua opinião final (ao menos em parte), isso é inerente à condição de quase monopólio da MS, espero que a comunidade de SO livre consiga uma fatia maior o bolo.

A muito tempo já deixei de usar o MS Office ou o IE, já me aventurei algumas vz no Linux com o finado Kurumin (foi uma pena que acabou), estou com muita vontade de usar o Ubuntu, só não o fiz por total falta de espaço no meu HD lotado, estou para adquirir uma nova máquina e certamente essa é uma das minhas prioridades.

Abraços...
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 09 de Outubro de 2009, 13:01
Citar
O programa que estamos discutindo pode ser temporizado como a seguir:

while(1) {
    outportb(0x378,0xFF);
    a = 10;
    outportb(0x378,0xFD);
    a = 10;


A linha a=10 é apenas para gastar tempo (similar a um sleep, de x milisegundos, onde x=??), voce pode medir a velocidade com um frequencímetro, mas ainda teremos o problema da latência variável do Windows...

1- Gil, vou testar essas linhas, voce me falando de latencia agora me veio uma duvida, meu pc é um celeron 2.1ghz que nao tem muito velocidade voce acha que se eu trocar pra um pc mais "parrudo" responderia melhor com maior velocidade?

2-supondo que alinhas que me passou fiquem "na mesma" eu eu radicalmente "migre" para o linux o programa acima entao funcionaria sem os famosos bugs do windows? eu teria um programa real com respostas em ms real?

Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 10 de Outubro de 2009, 23:44
Boa noite,

fiz os testes hoje com as APIS "QueryPerformanceCou nter" e "QueryPerformanceFre quency", seque em anexo as fotos dos resultados.

assim que eu resolver esse negócio azul que o UserPort esta causando no windows, eu boto o osciloscópio na paralela e coloco os resultados.

abraços
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 11 de Outubro de 2009, 08:48
Odail,

Citar
O programa que estamos discutindo pode ser temporizado como a seguir:

while(1) {
    outportb(0x378,0xFF);
    a = 10;
    outportb(0x378,0xFD);
    a = 10;



1- Gil, vou testar essas linhas, voce me falando de latencia agora me veio uma duvida, meu pc é um celeron 2.1ghz que nao tem muito velocidade voce acha que se eu trocar pra um pc mais "parrudo" responderia melhor com maior velocidade?

2-supondo que alinhas que me passou fiquem "na mesma" eu eu radicalmente "migre" para o linux o programa acima entao funcionaria sem os famosos bugs do windows? eu teria um programa real com respostas em ms real?

A diferença básica entre usar o Windows e outras soluções mais abertas (Linux, FreeDOS) nesse tipo de aplicação é a latência imprevisível e incontrolável do Windows. Por outro lado, nos "mundos" DOS (ex.: FreeDOS) e Linux (ex.:RT-Linux) há mais opções de ambientes apropriados para aplicações de tempo real e mais controle sobre a máquina / S.O.

Já fiz programas para controlar motores de passo em linguagem C / Assembly em ambiente DOS.

Mas, como diz o Fábio, é apenas a minha opinião...  :)

Está aí o Mach, que roda em Windows...

O programa que eu sugeri voce testar era para eu ter uma idéia da velocidade do teu sistema, a frequência de dezenas de Hertz que voce falou me pareceu baixíssima, mesmo em Windows. Este programa não usa o sleep e, assim, pode dar um pouco mais de informação sobre a "caixa preta" compilador / Windows.
Aliás, qual o Windows que voce usa?
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 11 de Outubro de 2009, 13:26
Citar
fiz os testes hoje com as APIS "QueryPerformanceCou nter" e "QueryPerformanceFre quency", seque em anexo as fotos dos resultados.
assim que eu resolver esse negócio azul que o UserPort esta causando no windows, eu boto o osciloscópio na paralela e coloco os resultados.

Poxa amigo, muito legal essa linhas de programação, o truque pra turbinar frequencia no windows deve ta por ai mesmo, que compilador vc esta usando pra programar, você conseguiu 10 MHZ onde na porta ou em simulação?

Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 11 de Outubro de 2009, 14:22
tou usando o Microsoft Visual C++ 6.0.

eu fiz essas medições incrementando a variável fCounter a cada ciclo e mostrando o resultado usando um timer de 1seg. Da pra ver essa parte do código nos printscreen.

Citar
você conseguiu 10 MHZ onde na porta ou em simulação?
Na verdade é pouco mais de 1MHz. esse foi o máximo que meu computador chegou. o que até pode ser melhorado.

---------------------------------------------------------------------
Atualizando...



Coloquei o osciloscopio na paralela e tive uma surpresa...

a 10khz o desvio foi menor que 10Hz... fiquei tao surpreso que vou até postar um video pra n duvidarem de mim...rs

a 50kHz a coisa ficou mais complicada, mas acredito que com alguns ajustes (nada de sobrenatural) é possível sim fazer um gerador mais ou menos confiável.

400kHz foi o maximo que consegui no meu pc.

vale lembrar que o gerador não estava sendo executado sozinho, existiam pelo menos duas outras aplicações que estavam exigindo muito do processador.



Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 11 de Outubro de 2009, 17:51
Cláudio,

Me explique o que está sendo mostrado, a onda quadrada é gerada pelo seu programa em C++ e há um osciloscópio (de que tipo digital / analógico?) conectado ao PC?

Qual a versão do seu Windows?
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 11 de Outubro de 2009, 17:58
Gil,

Estou utilizando o Windows XP, a onda esta sendo gerada pelo meu programa escrito em C, o osciloscópio é um PicoScope 2202
http://www.picotech.com/picoscope2202-specifications.html (http://www.picotech.com/picoscope2202-specifications.html) e a ponta de prova do osciloscópio esta ligada no pino 2 da porta paralela
(uma placa expansora da comtac. minha placa mãe n possui onboard).


Código: [Selecionar]
DWORD WINAPI Thread_uTimer(LPVOID lpParam){
LARGE_INTEGER freq, start, stop;
SetThreadAffinityMask(GetCurrentThread(), 2);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
QueryPerformanceFrequency(&freq);
while(1){
_outp(0xA800, 2);
QueryPerformanceCounter(&start);
do {
QueryPerformanceCounter(&stop);
} while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= Ton );

_outp(0xA800, 0);
QueryPerformanceCounter(&start);
do {
QueryPerformanceCounter(&stop);
} while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= Toff );

fCounter++;

}
return 0;
}
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 11 de Outubro de 2009, 23:04
Cláudio,


O Picoscope está instado no mesmo PC onde o seu software roda?

O Picoscope posui um buffer (memória interna) própria, de modo que as medições não seja influenciadas pelo Windows?

Voce teria a imagem gravada pelo sofware do Picoscope? A forma de onda é similar ao do seu programa? Como voce avaliou a diferença de 10Hz que disse haver?
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 12 de Outubro de 2009, 00:28
O Picoscope está instado no mesmo PC onde o seu software roda?
sim. esta.

Citar
O Picoscope posui um buffer (memória interna) própria, de modo que as medições não seja influenciadas pelo Windows?
sim. possui. a medição é feita totalmente via hardware. enviando apenas o necessário para gerar os gráficos.

Citar
Voce teria a imagem gravada pelo sofware do Picoscope? A forma de onda é similar ao do seu programa? Como voce avaliou a diferença de 10Hz que disse haver?
posso salvar os dados da aquisição em arquivo sim. mas, para visualizar vc tera q baixar o software e instalar no seu pc. essa diferença de 10hz eu pude notar no frequencimetro q o software possui. nos videos é possível analisar os dados, fica no rodapé do programa.
Título: Re: CLOCK em microsegundos
Enviado por: minilathe em 12 de Outubro de 2009, 01:24
Cláudio,

A princípo pode não ter nada a ver... Mas o fato do software em C++ e o Picoscope estarem no mesmo PC não é uma situação ideal do ponto de vista do sistema sendo medido x sistema medidor. Considerando que o Jitter, eventualmente, poderia afetar a ambos, é mais uma suspeita...

Voce poderia salvar o gráfico do osciloscópio em bitmap?

Voce disse que na frequência de 10.000Hz existe uma diferença de 10Hz. Que pode parecer pouco, mas é uma diferença de 10 1 pulsos a cada 10.000 pulsos, em cada segundo. Num motor de passo, o erro em frequência seria cumulativo, nesse caso, equivale ao mesmo se deslocar (ou não se deslocar) 1 passo a cada 100 1000 passos que recebe. Ou seja 1% 0,1% de erro de deslocamento a cada segundo.

Basicamente, esse erro vai ocorrer, é claro, se não houver sincronismo na geração dos pulsos, que poderia acarretar deslocamentos relativos entre os eixos X, Y, Z,.... do CNC. Se todos os pulsos estiverem sendo comandados simultaneamente pelo software (o que normalmente ocorre), a variação de frequencia é de pouca influência.
Porém, alterações muito intensas de frequência podem não ser acompanhadas pelo motor de passo, aliado a inércia do sistema mecânico da CNC. A variação máxima de frequência deverá estar restrita ao parâmetro de aceleração máxima do software CNC, que define a taxa de variação da velocidade do motor. E também não sei quais os valores usuais...
 
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 12 de Outubro de 2009, 09:31
Citar
A princípo pode não ter nada a ver... Mas o fato do software em C++ e o Picoscope estarem no mesmo PC não é uma situação ideal do ponto de vista do sistema sendo medido x sistema medidor. Considerando que o Jitter, eventualmente, poderia afetar a ambos, é mais uma suspeita...
não teria como, sao sistemas totalmente separados. a medição é feita via hardware, sem qualquer influência do windows.

Citar
Voce disse que na frequência de 10.000Hz existe uma diferença de 10Hz. Que pode parecer pouco, mas é uma diferença de 10 pulsos a cada 10.000 pulsos, em cada segundo. Num motor de passo, o erro em frequência seria cumulativo, nesse caso, equivale ao mesmo se deslocar (ou não se deslocar) 1 passo a cada 100 passos que recebe. Ou seja 1% de erro de deslocamento a cada segundo.
Na verdade, o erro é < 0.1%. a cada segundo pode ter até 10 pulsos a mais ou a menos.

se o erro for de 90%, perderia velocidade, mas a precisão no deslocamento nunca. Quem fizer um software nesse sentido, não pode mandar o motor rodar durante 1 7/128 de segundo. teria que contar os passos do motor para se certificar de que esta sendo efetuado corretamente e também para saber quando parar.

Citar

Basicamente, esse erro vai ocorrer, é claro, se houver deslocamentos relativos entre os eixos X, Y, Z,.... do CNC. Se todos os pulsos estiverem sendo comandados simultaneamente, a variação de frequencia é de pouca influência.
Porém, alterações muito intensas de frequência podem não ser acompanhadas pelo motor de passo, aliado a inércia do sistema mecânico da CNC.
Basicamente, esse erro vai ocorrer, é claro, se houver deslocamentos relativos entre os eixos X, Y, Z,.... do CNC. Se todos os pulsos estiverem sendo comandados simultaneamente, a variação de frequencia é de pouca influência.
Porém, alterações muito intensas de frequência podem não ser acompanhadas pelo motor de passo, aliado a inércia do sistema mecânico da CNC.
Como o gerador é um só para todos os eixos, acredito não haver problemas. Quanto as variações bruscas, qualquer sistema estará sujeito a elas, de uma forma ou outra.


Ok, sem stress.... não sou sócio do Bill Gates nem concorrente direto. E se voce tiver algum programa que rode rápido no Windows, conforme temos discutido aqui, será bem vindo...

Contra fatos, não há argumentos....  :)
Lembrabndo que, o meu propósito nesse tópico, era tentar gerar esse clock que o amigo Odail precisa.
Demonstrei que é possível. Nâo é um relógio atômico, mas é funcional. atende em 1000% as necessidades do nosso amigo.

no segundo printscreen, eu ajustei no programa os tempos de Ton e Toff para chegar mais próxmio dos 10kHz. (que ficaram com 49.800 nS)

O arquivo .psdata em anexo, poderá ser visualizado com o software PicoScope 6 que está disponível para download no site picotech.com
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 12 de Outubro de 2009, 12:30
Basicamente, esse erro vai ocorrer, é claro, se não houver sincronismo na geração dos pulsos, que poderia acarretar deslocamentos relativos entre os eixos X, Y, Z,.... do CNC. Se todos os pulsos estiverem sendo comandados simultaneamente pelo software (o que normalmente ocorre), a variação de frequencia é de pouca influência.
Porém, alterações muito intensas de frequência podem não ser acompanhadas pelo motor de passo, aliado a inércia do sistema mecânico da CNC. A variação máxima de frequência deverá estar restrita ao parâmetro de aceleração máxima do software CNC, que define a taxa de variação da velocidade do motor. E também não sei quais os valores usuais...

Gil, em um software para controle de CNC, deve ser gerado um clock principal e em cima desse clock principal é gerado os clocks para os motores (coisa de 10kHz?). Vamos supor que esse clock seja de 25kHz.
A largura dos pulsos nunca irá diminuir, tende a aumentar por motivos já conhecidos. O clock não tem necessidade de trabalhar a 25.000Hz cravados.
Então, o driver nunca vai deixar de receber algum pulso por largura insuficiente. Pensando assim, acredito eu, não teria como o motor perder passo.
Uma outra situação é a ausencia de clock, caso o Gerador de 25kHz falhe por alguns instantes, como por exemplo, ele desapareça com 250 ciclos (1%), o que dará uma pausa de 10mS, se esse tempo for prejudicial a usinagem, o programa tem como detectar esse erro e poderá corrigir (utilizando uma rampa de aceleração para fazer a retomada) ou simplesmente parar a usinagem.

E lembrando mais uma vez, não estamos desenvolvendo um software para controle de cnc, apresentei essa solução apenas para resolver o problema do nosso amigo criador do tópico. Em momento algum plantei a idéia de que o windows é melhor em algo comparado a qualquer outro SO.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 12 de Outubro de 2009, 12:38
Citar
tou usando o Microsoft Visual C++ 6.0.

Claudio, eu uso o C++ BUILDER vicê acha que posso executar esse codigo dentro dele  pra fazer um teste ou eu teria que  mudar pra VISUAL C?

Coloquei
Citar
o osciloscopio na paralela e tive uma surpresa...

a 10khz o desvio foi menor que 10Hz... fiquei tao surpreso que vou até postar um video pra n duvidarem de mim...rs

a 50kHz a coisa ficou mais complicada, mas acredito que com alguns ajustes (nada de sobrenatural) é possível sim fazer um gerador mais ou menos confiável.

400kHz foi o maximo que consegui no meu pc

Nusssaa Claudio estou com o sorriso ;D la na orelha cara, vc ter conseguido 400 hz no seu pc foi uma coisa incrivel pela discussao que ja tivemos aqui e 10.000 hz entao foi mais ainda.

testei no frequencimento no meu multimetro pra ver quanto o KCAM estava mandando de  frequencia pro motor eixo "Z "rodar e o resutado foi de 400hz e motor gira rapidão ate ai da pra mim tranquilo,

Teria como vc disponiblizar o codigo pra mim testar aqui na minha maquina? Claudio não some cara preciso muito de vc ;D
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 12 de Outubro de 2009, 12:45
o máximo que consegui foi 400.000Hz e não 400Hz. Mas isso foi no meu computador.

quanto ao builder, eu nunca nem vi a cara, nas C é C. Acredito que algumas modificações vc tera q fazer sim.

vou anexar o arquivo main.cpp, tenta rodar ele e ve o q acontece.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 12 de Outubro de 2009, 13:42
Opa desculpa Claudio nao prestei atenção realmente foi 400k o que conseguiu (muita coisa hein)?

no caso de fCounter++; eu poderia adicionar uma label do tipo print no builder pra mostrar a frenquencia na tela, é isso mesmo?

ja tenho threads criadas no meu programa, no caso seria so adicionar abaixo do while tipo assim:

while
{


      _outp(0x378, 2);
      QueryPerformanceCou nter(&start);
      do {
         SwitchToThread();
         QueryPerformanceCou nter(&stop);
      } while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= Ton );

      _outp(0x378, 0);
      QueryPerformanceCou nter(&start);
      do {
         SwitchToThread();
         QueryPerformanceCou nter(&stop);
      } while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= Toff );

      fCounter++;
}

claro eu teria qua adicionar os includes ton e toff

essas linhas SwitchToThread();seria necessaria no meu programa?
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 12 de Outubro de 2009, 13:50
essa é a função da fCounter. a cada segundo eu executo o seguinte código:

char str[15];
_snprintf(str, 15, "%i", fCounter); // Converte de long para char
SetWindowText(hLblFreq, str); // Mostra em um Label
fCounter = 0; // Reseta o contador

SwitchToThread(); é necessário para o windows processar outras threads. senão teu pc ficará congelado. Aconselho deixar a prioridade da thread como normal.

Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 12 de Outubro de 2009, 17:07
Olha meu codigo como ficou, nao deu nenhum erro mas tambem nao contou nada na Form1->LabelLoop->Caption = fCounter; a label ficou como na foto que esta abaixo, sera que você conseguiria achar algum erro? estou no meu trabalho e minha CNC3AX esta em casa e nao posso testar direto nos pinos da porta paralela agora.



//---------------------------------------------------------------------------
#include "manip8bits.h"
#include "porta.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#define IDC_CLOSE         1
#define DISP_FREQ   WM_USER + 1
#define Ton      50   // uSec
#define Toff   50   // uSec
#include <vcl.h>
#pragma hdrstop
#define DADOS 0x378
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TPorta *Lpt;
TForm1 *Form1;
unsigned long fCounter;

HWND hMain, hLabel, hLblFreq, hButtonExit;
HANDLE hThread;
HINSTANCE hInst;

DWORD WINAPI Thread_uTimer(LPVOID lpParam){
   LARGE_INTEGER freq, start, stop;
   
   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIM E_CRITICAL);
   
   QueryPerformanceFre quency(&freq);

   for(;){
            Lpt->Envia(DADOS, 2);
      QueryPerformanceCou nter(&start);
      do {
         SwitchToThread();
         QueryPerformanceCou nter(&stop);
      } while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= Ton );

      Lpt->Envia(DADOS, 0);
      QueryPerformanceCou nter(&start);
      do {
         SwitchToThread();
         QueryPerformanceCou nter(&stop);
      } while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= Toff );

      fCounter++;
                Form1->LabelLoop->Caption = fCounter;

   }
   return 0;
}


Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 12 de Outubro de 2009, 17:25
tua thread não esta sendo executada.
do jeito que está o Label iria incrementar infinitamente, até ocorrer erro.

no builder é possível jogar uma variável diferente de char direto no caption do label?

tu tentou compilar o arquivo main.cpp do jeito que esta? tira as linhas _outp e v no q da.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 13 de Outubro de 2009, 11:44
Citar
tu tentou compilar o arquivo main.cpp do jeito que esta? tira as linhas _outp e v no q da.

Opa Claudio desculpa a demora em responder, o 1º programa que postei nao rodava porque eu compilei apenas metade do codigo, rodei o main.ccp e fiz algumas modificaçoes de biblioteca de porta e FUNCIONOU!!!! ele criou o quadro "utimer" e mostra os resultados nela e mostra 9.499hz que é uma velocidade considerada alta pra mim, MUITO BOM MESMO, eu estava ate achando que isso nao era possivel mesmo, mas como o amigo GIL sempre dizia tem que haver uns "TRUQUES SUJOS" pra fazer a coisa funcionar ( se é assim que posso dizer).

MUITO OBRIGADO, agora vou testar direto na porta paralela pra ver se ela oscila nessa velocidade mesmo, você ja fez algum teste direto no PINO 2 da porta paralela?
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 13 de Outubro de 2009, 12:17
Legal que deu certo Odail,

se vc baixar os valores de ton e toff, vai aumentar a freq e vice-versa.
para um freq de 1kHz, defina como 500 (500 us).

Citar
MUITO OBRIGADO, agora vou testar direto na porta paralela pra ver se ela oscila nessa velocidade mesmo, você ja fez algum teste direto no PINO 2 da porta paralela?

Já fiz sim e até postei os resultados, consegui 400kHz medindo com osciloscopio.

Como vc esta fazendo o acesso a porta paralela? por device driver? qual?
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 13 de Outubro de 2009, 13:42
Amigo Claudio, eu so consegui em torno de 210KHZ, deve ser pelo fato de que estou processando um gerenciador de cyber cafe na minha maquina e deve estar cheio de threads dando prioridade.

estou ja adicionado ao programa um updown linkado a uma variavel com o nome de "repete"dentro de um laço"for" assim:

while(1){
      for(aux=0; aux<repete; aux++)
      /{
      Lpt1->Envia(0x378, 1);
      QueryPerformanceCou nter(&start);
      do {
      ................... ................... ......

desta forma com o updown eu posso incrementar a variavel "repete" para controlar os pulsos do motor a passo, ta ficando show e funcional, so ainda não testei na CNX3AX porque nao esta aqui, eu estou usando um LED ligado no pino 2 da porta paralela para monitorar e ele ta acendendo de boa.

outra coisa é como eu faria pra adicionar um controle do tipo SLIDER, pra controlar a FREQUENCIA em Ton e Toff? fiz umas tentativas mas nao consegui, seria:

Ton +Toff = a variavel do tipo int ou long?

se Ton +Toff não uma variavel como eu poderia manipular a frequerncia

Citar
Como vc esta fazendo o acesso a porta paralela? por device driver? qual?

Estou usando o componente USERPORT.SYS as vezes da uns bugs aqui e depois tenho que da STOP e depois START pra funcionar direito, qual voce usa?
 
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 13 de Outubro de 2009, 14:01
ao invés de usar:

#define Ton     500
#define Toff     500

crie variáveis do tipo double:

double Ton, Toff;

quando atualizar o valor do slider, jogue nessas varáveis.

pra esse teste eu usei o comando "allowio utimer.exe /a" junto com o porttalk. tem como liberar o acesso dentro do programa usando DeviceIOControl com o porttalk.sys.


Odail, para seguir a mesma linha e adicionar o slider, leia esse artigo do msdn:
http://msdn.microsoft.com/en-us/library/bb787531(VS.85).aspx (http://msdn.microsoft.com/en-us/library/bb787531(VS.85).aspx)
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 13 de Outubro de 2009, 14:32
Citar
crie variáveis do tipo double:

double Ton, Toff;

quando atualizar o valor do slider, jogue nessas varáveis.

no caso eu teria que incrementar uma unica variavel tipo long e o Ton e Toff teriam o mesmo tamanho e largura assim:

long  VELOCIDADE;

 VELOCIDADE = TrackBar1->Position;

e ficaria assim?
................... .............
      } while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= VELOCIDADE );
................... ..................
           } while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= VELOCIDADE );

se eu quisesse tempos diferentes pra Ton e Toff teria que usar duas variaveis do tipo long?



Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 13 de Outubro de 2009, 23:24
Odail,

Citar
no caso eu teria que incrementar uma unica variavel tipo long e o Ton e Toff teriam o mesmo tamanho e largura assim:

long  VELOCIDADE;

 VELOCIDADE = TrackBar1->Position;

e ficaria assim?
................... .............
      } while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= VELOCIDADE / 2); // Ton = 50%;
................... ..................
           } while( (double(stop.QuadPart - start.QuadPart) / freq.QuadPart * 1000000) <= VELOCIDADE / 2); Toff = 50%;

Citar
se eu quisesse tempos diferentes pra Ton e Toff teria que usar duas variaveis do tipo long?
exato.

fiz umas modificações no prog, oia como ficou:

Código: [Selecionar]
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#define MAIN_CAPTION "uTimer v1.0"

#define fMin 10
#define fMax 5000

HINSTANCE hInst;

HWND hMain;
HWND hLabel_Freq, hLabel_Duty, hLabel_Ton, hLabel_Toff;
HWND hScroll_Duty, hScroll_Freq;

HANDLE hThread;

unsigned long Freq, Measuring;
unsigned long Duty, Ton, Toff;

char buffer[25];

DWORD WINAPI Thread_uTimer(LPVOID lpParam){
LARGE_INTEGER freq, start, stop;
LARGE_INTEGER start_measure, stop_measure;

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

QueryPerformanceFrequency(&freq);

QueryPerformanceCounter(&start_measure);
while(1){

_outp(0xA800, 2);
QueryPerformanceCounter(&start);
do{
SwitchToThread();
QueryPerformanceCounter(&stop);
} while(((stop.QuadPart - start.QuadPart) * 1000000) / freq.QuadPart <= Ton);

_outp(0xA800, 0);
QueryPerformanceCounter(&start);
do{
SwitchToThread();
QueryPerformanceCounter(&stop);
} while(((stop.QuadPart - start.QuadPart) * 1000000) / freq.QuadPart <= Toff);

Measuring++;
QueryPerformanceCounter(&stop_measure);
if((stop_measure.QuadPart - start_measure.QuadPart) / freq.QuadPart >= 1){
_snprintf(buffer, 25, "Freq: %i Hz", Measuring);
SetWindowText(hLabel_Freq, buffer);
QueryPerformanceCounter(&start_measure);
Measuring = 0;
}
}
return 0;
}

LRESULT CALLBACK MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
switch(uMsg){
case WM_CREATE:{
SetWindowPos(hwnd, NULL, (GetSystemMetrics(SM_CXSCREEN) / 2) - (300 / 2), (GetSystemMetrics(SM_CYSCREEN) / 2) - (140 / 2), 300, 140, SWP_NOZORDER | SWP_SHOWWINDOW);

hLabel_Freq = CreateWindowEx(NULL, "STATIC", NULL, WS_CHILD | WS_VISIBLE, 10, 10, 130, 16, hwnd, 0, hInst, NULL);
hLabel_Duty = CreateWindowEx(NULL, "STATIC", NULL, WS_CHILD | WS_VISIBLE, 10, 30, 130, 16, hwnd, 0, hInst, NULL);
hLabel_Ton  = CreateWindowEx(NULL, "STATIC", NULL, WS_CHILD | WS_VISIBLE, 10, 50, 130, 16, hwnd, 0, hInst, NULL);
hLabel_Toff = CreateWindowEx(NULL, "STATIC", NULL, WS_CHILD | WS_VISIBLE, 10, 70, 130, 16, hwnd, 0, hInst, NULL);

hScroll_Freq = CreateWindowEx(NULL, "SCROLLBAR", NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ, 150, 10, 130, 16, hwnd, 0, hInst, NULL);
hScroll_Duty = CreateWindowEx(NULL, "SCROLLBAR", NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ, 150, 30, 130, 16, hwnd, 0, hInst, NULL);

SetScrollRange(hScroll_Freq, SB_CTL, fMin, fMax, TRUE);
SetScrollRange(hScroll_Duty, SB_CTL, 1, 99, TRUE);

Measuring = 0;

Duty = 50;
Freq = (1000000 / fMin);

Ton  = (Freq * Duty) / 100;
Toff = Freq - Ton;

_snprintf(buffer, 20, "Freq: %i Hz", Measuring);
SetWindowText(hLabel_Freq, buffer);
_snprintf(buffer, 32, "Duty: %i %%", Duty);
SetWindowText(hLabel_Duty, buffer);
_snprintf(buffer, 32, "Ton: %i us", Ton);
SetWindowText(hLabel_Ton, buffer);
_snprintf(buffer, 32, "Toff: %i us", Toff);
SetWindowText(hLabel_Toff, buffer);

SetScrollPos(hScroll_Duty, SB_CTL, Duty, TRUE);

hThread = CreateThread(NULL, 0, Thread_uTimer, NULL, 0, NULL);

break;}
case WM_HSCROLL:{
HWND hScroll = (HWND)lParam;
SCROLLINFO si;
int CurPos;

CurPos = GetScrollPos(hScroll, SB_CTL);

si.cbSize = sizeof(si);
si.fMask  = SIF_ALL;
GetScrollInfo(hScroll, SB_HORZ, &si);

switch(LOWORD(wParam)){
case SB_ENDSCROLL:{
if(hScroll == hScroll_Freq){
Freq = (1000000 / CurPos);

Ton  = (Freq * Duty) / 100;
Toff = Freq - Ton;

_snprintf(buffer, 25, "Ton: %i us", Ton);
SetWindowText(hLabel_Ton, buffer);

_snprintf(buffer, 25, "Toff: %i us", Toff);
SetWindowText(hLabel_Toff, buffer);
} else if(hScroll == hScroll_Duty){
Duty = CurPos;
Ton  = (Freq * Duty) / 100;
Toff = Freq - Ton;

_snprintf(buffer, 25, "Duty: %i %%", Duty);
SetWindowText(hLabel_Duty, buffer);

_snprintf(buffer, 25, "Ton: %i us", Ton);
SetWindowText(hLabel_Ton, buffer);

_snprintf(buffer, 25, "Toff: %i us", Toff);
SetWindowText(hLabel_Toff, buffer);
}
break;}
case SB_LEFT:{
CurPos--;
break;}
case SB_RIGHT:{
CurPos++;
break;}
case SB_LINELEFT:{
CurPos--;
break;}
case SB_LINERIGHT:{
CurPos++;
break;}
case SB_PAGELEFT:{
CurPos -= 10;
break;}
case SB_PAGERIGHT:{
CurPos += 10;
break;}
case SB_THUMBPOSITION:{
CurPos = HIWORD(wParam);
break;}
case SB_THUMBTRACK:{
CurPos = HIWORD(wParam);
break;}
}

SetScrollPos(hScroll, SB_CTL, CurPos, TRUE);

break;}
case WM_CLOSE:{
if(hThread != INVALID_HANDLE_VALUE) CloseHandle(hThread);
DestroyWindow(hLabel_Freq);
DestroyWindow(hLabel_Duty);
DestroyWindow(hLabel_Ton);
DestroyWindow(hLabel_Toff);
DestroyWindow(hScroll_Freq);
DestroyWindow(hScroll_Duty);
DestroyWindow(hwnd);
break;}
case WM_DESTROY:{
PostQuitMessage(0);
break;}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hInstNULL, LPSTR lpszCmdLine, INT nCmdShow){
MSG Msg;
WNDCLASSEX wc;

hInst = hInstance;

ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS;
wc.hInstance = hInstance;
wc.lpfnWndProc = MainWindowProc;
wc.hIcon = LoadIcon(hInstance, NULL);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wc.lpszClassName = "uTimer_MAINCLASS";
if(!RegisterClassEx(&wc)) return 1;

hMain = CreateWindowEx(0, "uTimer_MAINCLASS", MAIN_CAPTION, WS_CAPTION | WS_SYSMENU, 0, 0, 0, 0, HWND_DESKTOP, NULL, hInstance, 0);

while(GetMessage(&Msg, 0, 0, 0)){
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}

UnregisterClass("uTimer_MAINCLASS", hInstance);

return 0;
}
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 14 de Outubro de 2009, 13:36
Nossa Claudio, ficou muito massa assim, eu nao consegui rodar nem dessa vez fazendo modificações aqui, poderia disponibilizar o main.ccp? Pelo que pude notar vc fez modificações pra poder mexer na frequencia de operação correto?

 Como adicionar pra vc faz como rótulo, como telas e não Visual C + + e em codigo puro ou é arasstando botões do menu para o FORM?

 fiz o download de  Visual C + + 2008 Express Edition  pra testar melhor o codigo mas alguns erros da, você sabe se essa versão é direcionada uma tambem objetos?

 Qual você me indicaria pra começar? os codigos do visual C e C + + Builder so são tão compativeis pra arquivos .ccp (?), pros objetos ja da erros, e retirando os label's do 1 ° código que enviou deu certo ....


 Só mais uma pergunta vc programa em linguagens quantas?? D;
Título: Re: CLOCK em microsegundos
Enviado por: Cláudio F. em 14 de Outubro de 2009, 15:11
Como adicionar pra vc faz como rótulo, como telas e não Visual C + + e em codigo puro ou é arasstando botões do menu para o FORM?
é "código puro" mesmo. as referências vc encontra no http://msdn.microsoft.com/en-us/library/aa139672.aspx (http://msdn.microsoft.com/en-us/library/aa139672.aspx)

Citar
fiz o download de  Visual C + + 2008 Express Edition  pra testar melhor o codigo mas alguns erros da, você sabe se essa versão é direcionada uma tambem objetos?
é OOP sim. Os erros aconteceram pq é necessário configurar os parâmetros do projeto. vou anexar o prog em VC2008 compilado.

Citar
Qual você me indicaria pra começar? os codigos do visual C e C + + Builder so são tão compativeis pra arquivos .ccp (?), pros objetos ja da erros, e retirando os label's do 1 ° código que enviou deu certo ....

é compativel pq a linguagem C é padronizada. como eu não usei nenhuma biblioteca exclusiva do Visual C++ (com excessão da função _outp()), vc conseguiu compilar no builder.
Posta os erros que ocorreram. Talvez seja problema de conversão de tipos.

Citar
Só mais uma pergunta vc programa em linguagens quantas?? D;

Para aplicações windows, utilizo visual basic e C++ quando necessário.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 16 de Outubro de 2009, 20:44
Opa sumi um pouco por causa de trabalho mais estamos aqui de novo, e desde já agradecer o Nosso estimável Professor GIL pelas suas valiosas dicas sobre sistemas operacionais e suas limitações (aprendi bastante).

E jamais deixaria de agradecer da super hiper mega ajuda do meu amigão Claudio S. que restaurou a esperança que ja nem tinha mais na realização do meu projeto simples (mais que é muito importante pra mim) me devolvendo a visão que nem sempre tudo está perdido e que quase sempre há uma luz no fim do túnel.....

      MEU MUITO OBRIGADO A TODOS!!!!  ;D

E so pra não ficar falando aqui e provar que o esforço de voces não foram em vão em me ajudar, disponibilizo aqui meu projeto de interface de controle de motor a passo muito simples, mais que agora bota pressão nos motores e tira todo o proveito dos mesmo em VELOCIDADE MÁXIMA, graças as famosas linhas de programação QueryPerformanceFre quency e QueryPerformanceCou nter que definitamente salvarão esse projeto hobby e que foi possivel tirar todo proveito do motores a passo.....

Ainda não está pronto, mais quando estiver totalmente pronto vou disponibilizar o codigo aqui como fez o amigo Claudio S. pra quem quiser se aventurar e construir seus proprios controles com interface e tudo mais.

Gostaria ainda de contar com os amigos, pois ainda sou um pintinho saindo da "casca do ovo" e ainda faltam alguns ajustes pela frente...

OBRIGADO A TODOS

ABAIXO A FOTO DE COMO ESTA FICANDO A INTERFACE.
Título: Re: CLOCK em microsegundos
Enviado por: matrixlan1 em 28 de Outubro de 2009, 16:41
ja na fase final do programa de controle pra 3 motores XYZ, surgiu a necessidade de implantar uma sequencia de execução como no programa abaixo anexado a esta mensagem.

Claudio será que vc poderia me da uma força pra implantar?

sei que o principio é um listbox onde se adiciona todos os parametros e de DIR, VELOCIDADE, SENTIDO etc, e depois EXECUTA TUDO.

inclusive ja ate adicionei um listbox ao programa mas to meio perdido pra fazer executar os movimentos de dentro da lista para a porta paralela

Claudio será que vc poderia me da uma força pra implantar?

tem um post aqui no forum de um colega que estava montando mais ja é muito antigo veja:

http://www.guiacnc.com.br/index.php/topic,1197.0.html