Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: kennedy в Nov 19, 2008, 08:12



Титла: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Nov 19, 2008, 08:12
Здравейте,
от известно време се занимавам с направата на една машина за изработка на тръбички (свързана с моето хоби - ракетомоделизъм) и стигнах до момента с програмирането.
машината се управлява по помоща на контролер закачен на принтерския порт. нуждая се от програма която да изпраще определен брой "еденици" на даден пин или за сетване на пин да стои 0/1.
приемам всякакви предложения.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: laskov в Nov 19, 2008, 09:38
Навремето в ДОС имаше една програма, наречена debug. Та в нея, като напишеш
Цитат
о 378,ff
(o - ouput, i - input, т.е.  запис или четене в/от адрес от периферията), на паралелния порт получаваш само единици, а записа на 00 сваля всички битове на 0. Ако запишеш 01, на 2-ри пин на паралелния порт ще получиш 1, а на останалите (3-9) - 0. Ако запишеш 05, ще имаш единици на 2 и на 4. От този адрес можеш и да четеш. Напр. ако машината ти се управлява с 4 бита, можеш с останалите 4 да следиш някакви датчици.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: vstoykov в Nov 19, 2008, 10:44
Виж как съм го направил тук:
http://club-linux.hit.bg/

Части от кода:
Код
GeSHi (C++):
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <sys/io.h>
  4. #include <ctime>
  5. #include <cmath>
  6.  
  7. /* Обикновено адресът е 0x378 */
  8. #define portaddress 0x378
  9.  
  10. using namespace std;
  11.  
  12. /* Тази подпрограма праща данни на паралелния порт */
  13. void lptout(unsigned char value) {
  14.  
  15.  if (ioperm(portaddress,1,1)) {
  16.   cout << "error: Няма достъп до паралелния порт" << endl;
  17.   exit(1);
  18.  }
  19.  
  20.  outb(value,portaddress);
  21.  
  22. }
  23.  


Тук има готова програма, която приема десетично число (0-255) като параметър:
http://www.epanorama.net/circuits/lptout.c

Разположение на изводите: http://en.wikipedia.org/wiki/LPT


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Nov 19, 2008, 12:46
при мен пиновете имат следното значение
пин 2-посока на шиндела
пин 3-завъртане 1 стъпка.
пин 4- посока по хоризонтала
пин 5-стъпка по хоризонтала.

трябва да сетвам и 4-те едно временно .... т.е. 01111 за да се завъртят 2-та двигателя в една посока. правилно ли съм разбрал?

довечера ще пробвам да видя как ще реагират двигателите като си поиграя с това което си ми изпратил


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: laskov в Nov 19, 2008, 14:09
Сега малко трябва да гадаем... Според това, което пишеш, това трябва да е нещо като струг.  4 и 5 вероятно имат следното действие: Да приемем че ако 4 е с ниво 1, това за струга е движение на ножа надясно, а когато 4 е 0 - движение на ножа наляво. Броят импулси на пин 5 определя броят на стъпките на ножа. И така ако 4 е 1 и подадеш на 5 10 импулса, това ще премести ножа надясно с 10 стъпки, т.е. ти трябва да пишеш на порт 378 последователно 04 и 0С (пинове 2 и 3 за сега ги пренебрегваме). Трябва обаче да се съобразиш с това, колко широки трябва да са импулсите на пин 5, така че машината да успее да реагира, т.е. като запишеш 04 колко време да изчакаш преди да запишеш 0С и пак колко време да изчакаш преди да запишеш отново 04. Когато сменяш посоката (нивото на пин 4) пак ще трябва да изчакаш преди да подадеш  импулсите на пин 5.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Nov 19, 2008, 14:50
не е струг (в началото писах че е машина за навиване на тръби).
но на същия принцип е. 2 двигателя - единия върти шпиндела, другия мота наляво-надясно нишката.
ще видя какво пише за самите мотори като закъснение което трябва да има и продължителност на импулсите.
 


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: nikoni в Nov 19, 2008, 18:49
Тъй като винаги сетваш целия регистър, направи му една променлива,
На тази променлива сетваш нужните битове и тогава я записваш на порта.

Тайминга няма да е много добър (тимешеринг:().


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: gat3way в Nov 19, 2008, 19:43
Аз се съмнявам тези тръбички да трябва да се правят с хирургическа точност - там за времето преди да ти се schedule-ира процеса надали ще се случи фатално отклонение от желаната дължина на тръбичката. Предполагам де. Освен ако тези двигатели не се въртят наистина много бързо :)


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Nov 19, 2008, 20:23
двигателите са стъпкови т.е. на всяка 1-ца подадена на пин 3 или 5 един от двата двигателя се завърта на 1,8 градуса т.е. трябва да се подадат 200 импулса за един оборот на двигателя. промеждутъка между импулсите определя скороста ...
и така последно какво трябва да подам за да има 1-ца на 2 порт? 0100 0000 ?


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: MillWheel в Nov 19, 2008, 20:54
Преди време попаднах на една програмка, която експлоатира паралелния порт. Правена е за програматор на чипове, но може и да ви е от полза, като модел.

http://fbradasc.altervista.org/index.php?fbhpsessionid=ca966d2b160d65e5ff1b29b7a3682f1c&area=Projects/MicroControllers/FlP5


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: MillWheel в Nov 19, 2008, 21:00
и така последно какво трябва да подам за да има 1-ца на 2 порт? 0100 0000 ?
Измери с мултицет.
Този линк също може да е от полза: http://jaspreetscodezone.blogspot.com/2008/02/uln-2803-pinout-working.html


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: nikoni в Nov 19, 2008, 21:32
PP
X ---|R|------[Motor]
Y ---|R|------

R - 1k

X  ___+--+____    За 1 стъпка колко време трябва да е 1.

Ако ползваш дата-порта той е директен, т.е. като запишеш 1 излизат 5v.
За контрол порта наякой са инвертирани.

 Я дай една почти инстинска схема.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Nov 19, 2008, 21:57
ползвам този контролер
http://www.sirius-pcb.com/index.php?mod=catalog&show=14
с ето този драйвер
http://www.sirius-pcb.com/index.php?mod=catalog&show=23

ако ти говори нещо.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: nikoni в Nov 19, 2008, 22:34
PP
2  ---[R]------ [Motor 1 left]
3  ---[R]------ [Motor 1 right]
4  ---[R]------ [Motor 2 left]
5  ---[R]------ [Motor 2 right]


#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/io.h>

#define BASE 0x378

#define PORT_DATA BASE
#define PORT CTRL BASE + 2

#define M1_MASK 3
#define M2_MASK 12

#define STEP_DELAY usleep(20000)   /* 2 miliseconds */

static int reg_data = 0;

void m1_step_left() {
   reg_data |= 1;
   outb(reg_data, PORT_DATA);
   STEP_DELAY;
   reg_data &= M2_MASK;
   outb(reg_data, PORT_DATA);
}

void m1_step_right() {
   reg_data |= 2;
   outb(reg_data, PORT_DATA);
   STEP_DELAY;
   reg_data &= M2_MASK;
   outb(reg_data, PORT_DATA);
}

void m2_step_left() {
   reg_data |= 4;
   outb(reg_data, PORT_DATA);
   STEP_DELAY;
   reg_data &= M1_MASK;
   outb(reg_data, PORT_DATA);
}

void m2_step_right() {
   reg_data |= 8;
   outb(reg_data, PORT_DATA);
   STEP_DELAY;
   reg_data &= M1_MASK;
   outb(reg_data, PORT_DATA);
}

int para_setup() {
   reg_data = 0;
   if(ioperm(BASE, 3, 7) != 0) {
                perror("ioperm");
                exit(1);
        }
   outb(reg_data, PORT_DATA);
   return 0;
}

main() {
   if(para_setup()) exit (1);

   m1_step_left();
   sleep(1);
   m1_step_right();
   sleep(1);
   
   m2_step_left();
   sleep(1);
   m2_step_right();
   sleep(1);
}

M1 стъпка в ляво
ПОНЕ(може да е и по-вече) 1 сек пауза.
М1 стъпка в дясно
ПОНЕ 1 сек пауза.
M2 стъпка в ляво
ПОНЕ 1 сек пауза.
М2 стъпка в дясно
ПОНЕ 1 сек пауза.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: eniac111 в Nov 19, 2008, 22:43
Виж как съм го направил тук:
http://club-linux.hit.bg/

Сам ли си правил монетника?

//За стъпкови мотори използвам тази схема: http://blogs.msdn.com/coding4fun/archive/2007/11/02/5848155.aspx . Моторите са на 24V - от една пишеща машина. Все още не съм тествал схемата, предполагам че ще работи :)

Промяна: Отговора Ти е в коментара на драйвера :)))


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: laskov в Nov 20, 2008, 09:57
Пак малко ще гадая. Колко е тънка тази нишка? Според това колко е тънка и каква е стъпката в хоризонтална посока на един оборот на шпиндела, трябва да се предвиди и отместването на следващия пласт, така че нишката да не попада върху нишката от предишния пласт. А колко пласта се навиват? Предполагам, колкото по-малко, толкова по-добре? А има ли вероятност нишката да се скъса? Ще има ли блокировка? Извън темата: В Етъра до Габрово има едни машинки дето правят гайтани и имат блокировка при скъсване на нишка! Ако не се лъжа нишките са 6 или 8. Гледах ги и им се кефих доста време.  :)


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Nov 20, 2008, 15:12
Нишката варира и като широчина и на тази база се пресмята хода по Х. помислено е за блокировка при скъсване, самия контролер си има съответните изводи за подвързване (има едни изводи за нормално затворен бутон, който се води авариен стоп. нишката ще преминава през едно микро ключе и ще го държи затворено. макар че ми е малко чудно какво би скъсало една карбонова нишка ... ) . Пластовете ще са според зависи .... колкото се наложи 4,5,6 ....
дори различните пластове ще са с различна стъпка ....
но това ще са функции на една команда например "go"
go x6 y100 s200
което ще се преведе така "на всеки 100 стъпки за завъртане на оста трябват 6 по Х интервал между стъпките 200 мс "
тя ще си сметне на колко пулса по Y ще подаде 1 на Х
с помоща на тези параметри се определя и вида на намотките ...
а иначе ще има програма която да генерира параметрите , но това са по-елементарни неща.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Nov 22, 2008, 16:38
след като изгорих улн2003 на платката , след това и един мощен транзистор заради късо по платката, и след замяната им, и след дозапояването на рейтката, успях да подкарам двигателя отговарящ за оста Х. пин 2 и 3 пин 2 е за посока, пин 3 за стъпка. използвах първата програма която се компилира без проблем. статирайки я с параметър 1 и 3 двигателя славно започна да прави стъпки. т.е. трябва на пина за стъпка да се сетва и 0, защото той не минава сам към 0. ...
другото което ми направи впечатление е, че трябва да съм роот за да имам достъп до порта.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: vstoykov в Nov 24, 2008, 14:03
Може да се комбинира C и Bash (когато не разбирам някой език добре смесвам няколко езика за програмиране - понякога се получават много бавни програми, но поне не съм губил време в програмиране).  Пример:

Код:
#/bin/bash

lptout някакво_число
usleep 1000000 # 1 секунда
lptout някакво_число
usleep 1000000 # 1 секунда
lptout някакво_число
usleep 1000000 # 1 секунда
lptout някакво_число
usleep 1000000 # 1 секунда


Точността във времето не е голяма, но и при варианта без Bash няма да е кой  знае колко голяма (особено, ако има натоварване в момента с някаква тежка задача).

Ако искаш да пишеш директно двоични числа може да ползваш тази програма на Perl:

Код:
#!/usr/bin/perl

$total = 0;

chomp($binnumber = ($ARGV[0]));

@binnumber = split(//, $binnumber);
$length = @binnumber;

if ( $binnumber[7] == 1 ) {
 $total += 1;
}
if ( $binnumber[6] == 1 ) {
 $total += 2;
}
if ( $binnumber[5] == 1 ) {
 $total += 4;
}
if ( $binnumber[4] == 1 ) {
 $total += 8;
}
if ( $binnumber[3] == 1 ) {
 $total += 16;
}
if ( $binnumber[2] == 1 ) {
 $total += 32;
}
if ( $binnumber[1] == 1 ) {
 $total += 64;
}
if ( $binnumber[0] == 1 ) {
 $total += 128;
}

print "$total\n";
exit(0);

Задължително се пишат и 8-те бита на двоичното число.

Примерно ползване в скрипт:

Код:
#/bin/bash

lptout $(bin2dec.pl 00000100)
usleep 1000000 # 1 секунда

lptout $(bin2dec.pl 00000010)
usleep 1000000 # 1 секунда

lptout $(bin2dec.pl 00000111)
usleep 1000000 # 1 секунда

lptout $(bin2dec.pl 00000000)   # нулиране


Смятам, че последния вариант изглежда най-разбираем и удобен за редактиране.



Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Nov 24, 2008, 16:07
проблема е че за 1 оборот ще са необходими 1000-2000 импулса, за една навивка около 20 оборота т.е. 20000-40000 реда.
по скоро команда която подава серия от импулси например
go 1 2000 1 500 200
parameter 1 = посока по х
parameter 2 = брой импулси по х
parameter 3 = посока по y
parameter 4 = брой импулси по Y
parameter 5 = закъснение в милисекунди.
като програмата трябва да си раздели x/y за да види на колко импулса по едната ос трябва д аподаде импулс по другата ос.
това сложно ли ще бъде?


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Dec 14, 2008, 17:34
такаа, има програмата (благодаря Станиславе) но възникна един проблем, при тестовете се оказа, че при зададени например 10000 стъпки през 100 мс се усеща неравномерно въртене, усеща се тук таме някое засичане. Отдавах го на хардуерната част, докат не изпробвах програмата под RTOS (ubuntu 8.10) .. там същата тази програма (дори не съм си играл да я прекомпилирам) работеше гладко без да се усеща някакво накъсване при далеч по-кратки интервали 50мс ....
на какво може да се дължи това нещо и как мога в една не РТОС да подавам информация през порта без да ми се пречкат ?


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: spirtbrat в Dec 15, 2008, 11:50
Ами, дължи се точно на разликите между Ubuntu и RTOS Ubuntu (както и Ubuntu Studio). Ядрото си има особености свързани с многозадачността и поведението му, както сигурно знаеш, зависи от настройката му. В RTOS системите, то е настроено така, че да е много отзивчиво с цел програмите да вървят изключително гладко. А в стандартните системи се залага на по-добрата скалируемост, тъй като отзивчивостта не е критичен фактор при тях.
http://en.wikipedia.org/wiki/Real_time_operating_system ($2)
http://www.ibm.com/developerworks/linux/library/l-real-time-linux/ ($2)
http://www.linuxdevices.com/news/NS8393438079.html ($2)


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Dec 15, 2008, 14:14
да, но разликите са фрапантни ... би следвало да има начин и с обивновенна ос да се управлява ...
нещо бъркам някъде.
когато печаташ на принтера, ако така се бави .... ще печата 1 страница на минута


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: spirtbrat в Dec 16, 2008, 12:28
Принтера си има собствена памет. Когато си получи страницата, тогава започва да принтира, а не да му се подава буква по буква :)
Ти искаш да подаваш сигнали на твоята машинка един по един и без никакво забавяне. Това няма как да стане със стандартна система. Замисли се - като си пуснеш музика, тя трябва да свири без прекъсване, но на обикновената система аудио потока не е непрекъснат. Затова си има буфери, двойни буфери и дори тройни буфери за по-тежките задачи, които трябва да се изпълняват без прекъсване като 3D графика, HD видео възпроизвеждане и т.н.

Стандартната система, като получи команда и се заеме със задача, има нужда да извърши определен брой операции, за да може да е на разположение за следващата команда. Тези операции отнемат различни по-продължителност отрязъци от време в зависимост от типа им. В многозадачна среда организацията на работа на системата е сложна и има множество подробности и особености.

RTOS системите целят да направят тези интервали от време, през които системата не е на разположение, еднакви по продължителност и възможно най-кратки.
На тебе ти трябва точно такава система.

Ако се интересуваш, почети малко в нета. Хората са го обяснили по-добре от мен.


Титла: Re: помощ за програма за управление на принтерския порт.
Публикувано от: kennedy в Dec 16, 2008, 16:19
прав си, не помислих за буферите ....