Датчик остановки/окончания филамента из “мыши”
Но дальнейшая исследование показало, что без компьютера мышь не “загоралась”. Это удалось решить высоким уровнем на контакте D+. Но как оказалось, каждый раз режим перехода в ожидание и нахождение в нём был очень разный по времени и никак не удавалось разработать работающий алгоритм.
Поиск способа получения данных от мыши, привёл к нескольким ссылкам, где демонстрировалось получение координат перемещения мыши платой Arduino, но нужен был 'грызун' поддерживающий протокол обмена PS/2. Т.е. можно использовать для датчика не фантомное мигание, а реальное перемещение. Только теперь двигается уже не мышь, а филамент мимо сенсора. К сожалению мыши стандарта PS/2 поблизости не оказалось, но “интернет” подсказал, что обычно их делают универсальными 2-х стандартными PS/2 – USB. Мой подопытный образец A4TECH Model:X5-60MD хоть и имел разъем USB, но встречалось упоминание о продаже такой модели в двух видах. Я решил попробовать, и попытка оказалось успешной.
Теперь когда выяснилось, что моя мышь поддерживает протокол обмена PS/2. Из нескольких разных программ и библиотек работы с PS/2, мне удалось найти работающую с имеющейся в наличии контроллером: Deek-Robor Pro Micro на ATmega32u4, определяется как Arduino Leonardo. Мышь извлечена из корпуса и прикручена к распечатанной “направляющей”. Филамент свободно проходит в 2мм отверстие по центру сенсора на уровне “стола” т.е. 2,5 мм от сенсора.
В качестве алгоритма работы был реализован следующий порядок действий: если не было движения, т.е. считываются нулевые перемещения за последние 3 секунды и установлен высокий уровень на входе управления (G-code: M42 P4 S255), то подаётся высокий уровень на выход – 'звуковой сигнал'. Прототип работает с светодиодом, в дальнейшем в место светодиода, будет использоваться, выпаянная из модуля дисплея “пищалка”.
Т.е. если прозвучал звуковой сигнал, то желательно оперативно подойти к принтеру и возможно удастся исправить аварийную ситуацию, например: подтолкнуть пластик при образовании “проточки” или вставить новый при его окончании и т.п.
Саму схему распайки не привожу т.к. для реализации данной логики подойдёт практически любой Arduino-совместимый контроллер любой формы и размера, со своими номерами контактов. Для работы необходимо 3 цифровых выхода и 1 вход.
#define MDATA 6 – к контакту DATA PS/2 мыши.
#define MCLK 5 – к контакту CLK PS/2 мыши.
#define ledgnd 8 – можно не считать, лень было землю для светодиода тянуть.
#define led 7 – к контакту на индикацию/звук.
#define pinIn 9– вход признака необходимости сигнализации, к контакту D4 (и т.п.) SERVOS RAMPS 1.4.
Размер задержки (3 сек.) регулируется размером матрицы запоминаемых значений, через константу myzSize, сейчас проверка идёт 5 раз в сек (задержка в конце цикла 200 мсек.) и при 15 значениях будет ~3 сек. Для установки признака необходимости сигнализации, при остановке филамента, можно использовать любой pin Dx (D4,D5 …) на разъемах SERVOS, AUX-1 и AUX-2 на плате RAMPS 1.4. Ими можно управлять командами типа M42 P4 S255 и M42 P4 S0 и т.п. Которые вводятся из командной строки pronterface и т.п. программ или можно автоматически вставлять в G-code в момент его создания, например вкладка Custom G-code в Slic3R. Питание контроллера и мыши также можно организовать с контактов SERVOS RAMPS 1.4.
Несколько фото.
Площадка для крепления платы мыши и направляющая для филамента.В сборе.Со стороны платы мыши.Филамент не движется, загорелся светодиод.Вывод. Поставленная цель – сделать недорогой, но надёжный датчик остановки/окончания филамента из простой мыши, вполне осуществима.
Спасибо за внимание.
И, конечно, буду рад ответить на ваши вопросы, если таковые будут.
Тест программы. Взято на arduino.cc и творчески дополнено.
[CODE]/*
* an arduino sketch to interface with a ps/2 mouse.
* CLK(white) DATA(red) GND(green) 5V(blue)
* Also uses serial protocol to talk back to the host
* and report what it finds.
*/
/*
* USB-PS/2 - Pin 5 is the mouse D+ pin, pin 6 is the D- pin
*/
#define MDATA 6
#define MCLK 5
#define ledgnd 8
#define led 7
#define pinIn 9
#define myzSize 15
int myz[myzSize]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
/*
* according to some code I saw, these functions will
* correctly set the mouse clock and data pins for
* various conditions.
*/
void gohi(int pin)
{
pinMode(pin, INPUT);
digitalWrite(pin, HIGH);
}
void golo(int pin)
{
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void mouse_write(char data)
{
char i;
char parity = 1;
// Serial.print('Sending ';);
// Serial.print(data, HEX);
// Serial.print(' to mouse
';);
// Serial.print('RTS';);
/* put pins in output mode */
gohi(MDATA);
gohi(MCLK);
delayMicroseconds(300);
golo(MCLK);
delayMicroseconds(300);
golo(MDATA);
delayMicroseconds(10);
/* start bit */
gohi(MCLK);
/* wait for mouse to take control of clock); */
while (digitalRead(MCLK) == HIGH)
;
/* clock is low, and we are clear to send data */
for (i=0; i < 8; i++) {
if (data & 0x01) {
gohi(MDATA);
}
else {
golo(MDATA);
}
/* wait for clock cycle */
while (digitalRead(MCLK) == LOW)
;
while (digitalRead(MCLK) == HIGH)
;
parity = parity ^ (data & 0x01);
data = data >> 1;
}
/* parity */
if (parity) {
gohi(MDATA);
}
else {
golo(MDATA);
}
while (digitalRead(MCLK) == LOW)
;
while (digitalRead(MCLK) == HIGH)
;
/* stop bit */
gohi(MDATA);
delayMicroseconds(50);
while (digitalRead(MCLK) == HIGH)
;
/* wait for mouse to switch modes */
while ((digitalRead(MCLK) == LOW) || (digitalRead(MDATA) == LOW))
;
/* put a hold on the incoming data. */
golo(MCLK);
// Serial.print('done.
';);
}
/*
* Get a byte of data from the mouse
*/
char mouse_read(void)
{
char data = 0x00;
int i;
char bit = 0x01;
// Serial.print('reading byte from mouse
';);
/* start the clock */
gohi(MCLK);
gohi(MDATA);
delayMicroseconds(50);
while (digitalRead(MCLK) == HIGH)
;
delayMicroseconds(5); /* not sure why */
while (digitalRead(MCLK) == LOW) /* eat start bit */
;
for (i=0; i < 8; i++) {
while (digitalRead(MCLK) == HIGH)
;
if (digitalRead(MDATA) == HIGH) {
data = data | bit;
}
while (digitalRead(MCLK) == LOW)
;
bit = bit << 1;
}
/* eat parity bit, which we ignore */
while (digitalRead(MCLK) == HIGH)
;
while (digitalRead(MCLK) == LOW)
;
/* eat stop bit */
while (digitalRead(MCLK) == HIGH)
;
while (digitalRead(MCLK) == LOW)
;
/* put a hold on the incoming data. */
golo(MCLK);
// Serial.print('Recvd data ';);
// Serial.print(data, HEX);
// Serial.print(' from mouse
';);
return data;
}
void mouse_init()
{
gohi(MCLK);
gohi(MDATA);
// Serial.print('Sending reset to mouse
';);
mouse_write(0xff);
mouse_read(); /* ack byte */
// Serial.print('Read ack byte1
';);
mouse_read(); /* blank */
mouse_read(); /* blank */
// Serial.print('Sending remote mode code
';);
mouse_write(0xf0); /* remote mode */
mouse_read(); /* ack */
// Serial.print('Read ack byte2
';);
delayMicroseconds(100);
}
void setup()
{
pinMode(ledgnd, OUTPUT);
pinMode(led, OUTPUT);
pinMode(pinIn, INPUT);
digitalWrite(led, HIGH);
digitalWrite(ledgnd, LOW);
delay(200);
digitalWrite(led, LOW);
//Serial.begin(9600);
mouse_init();
}
/*
* get a reading from the mouse and report it back to the
* host via the serial line.
*/
void loop()
{
char mstat;
char mx;
char my;
int mz;
int mi;
/* get a reading from the mouse */
mouse_write(0xeb); /* give me data! */
mouse_read(); /* ignore ack */
mstat = mouse_read();
mx = mouse_read();
my = mouse_read();
for (int thisZ = 0; thisZ < myzSize-1; thisZ++) {
myz[thisZ] = myz[thisZ+1];
}
myz[myzSize-1] = int(my);
myz[myzSize-1] = abs(myz[myzSize-1]);
mz = 0;
for (int thisZ = 0; thisZ < myzSize; thisZ++) {
mz = mz + myz[thisZ];
//Serial.println(mxz[thisZ], DEC);
}
//Serial.println(mz, DEC);
mi = digitalRead(pinIn);
//Serial.println(mi, DEC);
if ((mz < 10) and (mi == HIGH)) {
digitalWrite(led, HIGH);
}
else {
digitalWrite(led, LOW);
}
digitalWrite(ledgnd, LOW);
/* send the data back up */
//Serial.print(mstat, BIN);
//Serial.print(' X=';);
//Serial.print(mx, DEC);
//Serial.print(' Y=';);
//Serial.print(my, DEC);
//Serial.println();
delay(200); /* twiddle */
}
[/CODE]
Еще больше интересных статей
Боремся с ошибкой "Move out of range: -25.000 175.000 134.885 [135570.196]"
Подпишитесь на автора
Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.
Отписаться от уведомлений вы всегда сможете в профиле автора.
Скрипт для очистки сопла под прошивку Klipper
Подпишитесь на автора
Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.
Отписаться от уведомлений вы всегда сможете в профиле автора.
Blue Pill & SSD1306, ну очень маленькие.., но 32 бит!
Подпишитесь на автора
Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.
Отписаться от уведомлений вы всегда сможете в профиле автора.
Решил я тут попробовать перейти с 8 бит на 32.
Готовы...
Комментарии и вопросы
да наверняка, что от новое при...
они там придумали уже как без....
потому что объект печати значи...
Подскажите, почему слой, идущи...
Всем привет! Только сегодня пр...
Простоял без дела принтер пару...
Добрый вечер.Изодрал я за 4 го...