Перчатка Mark gauntlet v4.2

В данной статье я постараюсь изложить суть моего проекта и показать процесс, который из наброска робота-собаки перетёк в заказ печатных плат для перчатки

Начало

Перчатка вытекла прямиком из моего проекта Mark, кроме того она является его значимой частью, так что начать следует с него.

Самый первый прототип робота был сделан в один из вечеров лета 2018 года. Это был четвероногий робот, состоящий из 8 сервоприводов SG90 (обычных синих) и кусков гвоздей. Соединялось всё это термоклеем и не имело ни единого шанса на нормальную работу ввиду очень неудачного распределения массы. Но я этого не знал и в тот же вечер заставил его шагать по прямой, а ещё через минут 15 после этого плата, через которую шло питание, задымилась и на столе оказался отпаявшийся линейный стабилизатор (к слову я так и не понял что там произошло).

Починить эту горку термоклея гвоздей и изоленты я так и не смог. В своё оправдание могу сказать, что в тот момент я не умел паять, из электроники понимал только что нельзя замыкать + и -, а о существовании 3D печати и не слышал.

В конце лета заказал себе первый принтер - Anet A8.

Обычный принтер для ознакомления с технологией: рама из акрила, кинематика с "дрыгостолом" и шумные моторы (скорее их драйвера)

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

Данное творение так и не заходило, но сподвигло меня на создание других версий. Возможно для моих червероногих роботов сделаю отдельную статью, так что просто дам последовательность из фотографий версий.

Последняя версия сейчас обзаводится корпусом, но уже нормально ходила и имеет неплохую грузоподъёмность.

С последней и предпоследней версией я победил на 2 мероприятиях и решил расширять серию Mark. Именно так на скорую руку я записал относительно нереальные планы на роботов, включая большие металлические базы для роботов. Но затем я всё же переосмыслил идею серии - можно же сделать реально интересную систему марсоходов, которая может себя показать и на Земле.

Собственно вот как я пока что это позиционирую:

Система роботов Mark - это исследовательский комплекс для автономного исследования местности, в частности - поверхности Марса.​

Mark 6 - основная база, предназначен для защиты остальных роботов от неблагоприятных условий.​

Mark 3 - основной разведчик, благодаря ногам может взбираться на уступы, также имеет 4 колеса.​

Mark 4 - шнекоход, также выполняет роль спасательного аппарата.  ​

Mark 5 - инсектоид с крыльями и 6 ногами. Может использоваться для изучения очень узких проходов.​

Mark 7 - робозмея, также как и Mark 5 может исследовать узкие проходы и отверстия.​

Mark gauntlet – перчатка для ручного управления всеми роботами.​​

Из представленных роботов у меня есть почти готовые Mark 6, Mark 4, ну и собственно Mark 3 и Mark gauntlet.

Из интересного по ним пока есть только основа Mark 6 и его шасси, которые пока печатаются 

Разработка перчатки: версия 1

Первая версия перчатки была сделана весной 2020 года и сразу заработала с тестовым стендом, но там мало что могло не сработать: я использовал обычный радиомодуль на 433 МГц с антенной из куска провода. Более подробно там есть в видео (моё первое видео, так что там всё очень посредственно) https://youtu.be/eEAHhr9Suug?t=194

Разработка перчатки: версия 2

Вторая версия была уже через 2 недели, так как она являлась прямым продолжением первой почти во всём.

Тут уже был радиомодуль nrf24l01, несколько режимов работы и выбор канала передачи. На работу перчатки можно глянуть в видео https://youtu.be/P_fq7KkfJrI

Кроме того я решил пойти с этой версией на фестиваль Rukami. С этого момента перчатка уже стала основным направлением работ на 2-3 месяца, что выдало в итоге неплохой результат.

Разработка перчатки: версии 3 и 4

Обе имеют схожий функционал и были сделаны каждая за пару дней.

3 версия:

Функционал:

  • WiFi модуль esp8266

  • Радиомодуль NRF24l01+

  • Мини радиомодуль на 433 МГц

  • Bluetooth модуль

  • Акселерометр + гироскоп на перчатке

  • Панель управления с OLED дисплеем

В целом получилась нормальная версия, но её было бы сложно повторять из-за пайки навесом прямо на корпусе. Вот подобие описания этой версии https://youtu.be/52WvejA6dyk .

4 версия:

Тут уже я взял всё что подходило под концепцию и добавил к этому контроллер Atmega2560

Видео с процессом её создания:

Функционал:

  • WiFi модуль

  • Радиомодуль NRF24L01+

  • Радиомодуль LoRa

  • MP3 плеер и динамик к нему

  • ИК- светодиод (для простейшей связи)

  • Мощные адресные светодиоды сбоку

  • Акселерометр+гироскоп

  • Датчик цвета + жестов

  • Панель управления с OLED дисплеем

На этом можно было бы и остановиться, но я решил пойти дальше и сделать версию 4.2

Версия 4.2 или завершающий штрих перчатки

Про уже спроектированные части я расскажу подробно, но платы пока ещё не пришли, так что сборку и результат уже покажу в следующей статье

Основа возвращается с первой версии из-за подходящей геометрии

Перчатка скорее всего останется с версии 4

Для питания будут использоваться 3 аккумулятора 18650 на 3.4 А*ч каждый, что обеспечит достаточно большую автономность. Крепиться это будет на плечо.

Почти вся электроника будет распаяна на 2 печатные платы, которые соединятся вместе

Ну и первоначальный код, который будет использоваться для теста на работоспособность. В нём я не использовал пока только LoRa модуль. Ссылка на гитхаб: https://github.com/Madjogger1202/Mark_GauntletV4.2/blob/main/src/main.cpp

Дальнейшее создание этой версии будет уже в ближайшее время.

Тестовый код
/*
  Hi stranger, this is main code file for this project
  I'm not a 100% programmer, but i can make electronics work,
  so i will be grateful if you add any features

  it is fully opensource project, so anyone can build stuff based on this code 

  have a great time reading this badly written working code (^_^) 

*/

#include <Arduino.h>      // why not...
#include <Wire.h>
#include <SPI.h>
// i have to make all modules work, so i will use some libraris to make life easier
//1) Display.      im using 0.96 oled from china, it is not standart at dimentions, bt i like how it looks in final designs :)
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> // Adafruit librari works 50/50, it depends on display driver (yes, they can hava same names, bt diffrent drivers)

//2) RGB Led panel.       LEDs 2812 (8-bit panel) 
#include <FastLED.h>

//3) NRF24L01+ 
#include <nRF24L01.h>
#include <RF24.h>

//4)APDC9960 usefull sensor
#include "Adafruit_APDS9960.h"

//5) LoRa radio sx1278
#include <RH_RF95.h>

//6) MPU6050 gyro + acsel
#include <Adafruit_Sensor.h>
#include <Adafruit_MPU6050.h>

//7) MP3 module
#include <DFPlayer_Mini_Mp3.h>

// first switches connection
int8_t first_sw[8] = { A14, A13, A12, A11, A10, A9, A8, A7 };

// second switches connection
int8_t second_sw[8] = { 38, 37, 36, 35, 34, A6, 32, A15 };

// buttons connection
int8_t buttons[4] = { A3, A1, A0, A2 };

#define LED1 10
#define LED2 11

#define JOY_X A6
#define JOY_Y A5

#define POT A4

#define LORA_D0 42
#define LORA_NSS 43
#define LORA_RST 44

#define NRF_CSN 40
#define NRF_CE 41

#define IR_LED 7
#define R_LED 4
#define G_LED 5
#define B_LED 6

#define WS_LED 45



#define LED_PIN     45
#define NUM_LEDS    8
#define BRIGHTNESS  20
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100 

CRGBPalette16 currentPalette;
TBlendType    currentBlending;
extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

RF24 radio(NRF_CE, NRF_CSN);

Adafruit_MPU6050 mpu;

Adafruit_SSD1306 display(128, 32, &Wire, -1);

Adafruit_APDS9960 apds;

volatile bool irqMPU;
volatile bool irqAPDC;

struct allData
{
  volatile boolean irqMPU;
  volatile boolean irqAPDC;

  bool stable;
  int8_t x_acs;
  int8_t y_acs;
  int8_t z_acs;

  uint8_t mode;
  uint8_t channel;

  uint16_t button;
  
  uint16_t potData;
  uint16_t joyX;
  uint16_t joyY;

  uint8_t led1Mode;
  uint8_t led2Mode;

  uint8_t redLedMode;
  uint8_t blueLedMode;
  uint8_t greenLedMode;

  uint8_t wsLedMode;

  

}mainData;

struct radioData
{
  bool stable;
  int8_t x_acs;
  int8_t y_acs;
  int8_t z_acs;

  uint8_t mode;
  uint8_t channel;

  uint16_t button;
  
  uint16_t potData;
  uint16_t joyX;
  uint16_t joyY;

} telemetriData;

void readMode();
void readCh();
void readAcs();
void readJoy();
void readPot();
void readButtons();
void sendNRF();
void sendBL();
void sendLoRa();   // will reliase it soon
void displayInfo();
void FillLEDsFromPaletteColors( uint8_t colorIndex);
void ChangePalettePeriodically();
void SetupTotallyRandomPalette();
void SetupBlackAndWhiteStripedPalette();
void SetupPurpleAndGreenPalette();
// at all it is possible to create up to 256 diffrent modes,
// but if you need more - connect mode counter with channel counter (maybe partly)
void n1Mode();
void n2Mode();
void n3Mode();
void n4Mode();
void n5Mode();
void n6Mode();
void n7Mode();
void n8Mode();
void n9Mode();
void n10Mode();
void n11Mode();
void n12Mode();



void acsel()
{
  mainData.irqMPU=true;
}
void gesture()
{
  mainData.irqAPDC=true;

}

const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM =
{
    CRGB::Red,
    CRGB::Gray, // 'white' is too bright compared to red and blue
    CRGB::Blue,
    CRGB::Black,
    
    CRGB::Red,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Black,
    
    CRGB::Red,
    CRGB::Red,
    CRGB::Gray,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Blue,
    CRGB::Black,
    CRGB::Black
};




void setup() 
{
  for(int i=0;i<8;i++)
    pinMode(first_sw[i], INPUT_PULLUP);
  for(int i=0;i<8;i++)
    pinMode(second_sw[i], INPUT_PULLUP);
  for(int i=0;i<4;i++)
    pinMode(buttons[i], INPUT_PULLUP);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  analogWrite(LED1, 10);
  analogWrite(LED2, 100);
  
  pinMode(JOY_X, INPUT);
  pinMode(JOY_Y, INPUT);

  pinMode(POT, INPUT_PULLUP);
  
  pinMode(LORA_D0, OUTPUT);
  pinMode(LORA_NSS, OUTPUT);
  pinMode(LORA_RST, OUTPUT);
  
  pinMode(NRF_CSN, OUTPUT);
  pinMode(NRF_CE, OUTPUT);
  
  pinMode(IR_LED, OUTPUT);
  pinMode(R_LED, OUTPUT);
  pinMode(G_LED, OUTPUT);
  pinMode(B_LED, OUTPUT);
  
  pinMode(WS_LED, OUTPUT);

  Serial.begin(115200);
  Serial2.begin(9600);
  mp3_set_serial(Serial2);
  mp3_set_volume(10);
  mp3_play (1);
  if (!mpu.begin())
    Serial.println("Sensor init failed");
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.display();
  display.clearDisplay();
  
  display.display();
  if(!apds.begin())
    Serial.println("failed to initialize device! Please check your wiring.");
  apds.enableProximity(true);
  apds.enableGesture(true);
  radio.begin();                                      
  radio.setChannel(100);                               
  radio.setDataRate     (RF24_1MBPS);                   
  radio.setPALevel      (RF24_PA_HIGH);                 
  radio.openWritingPipe (0x1234567899LL);               
  radio.setAutoAck(false);

  attachInterrupt(0, acsel, RISING);
  attachInterrupt(1, gesture, RISING);

  Serial1.begin(9600);         // bluetooth module connected to Serial1 
  delay(2000);
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
    
    currentPalette = RainbowColors_p;
    currentBlending = LINEARBLEND;
 // mp3_stop ();
  
  
}

void loop()
{
 readMode();
 readCh();
 readAcs();
 readJoy();
 readPot();
 readButtons();

 
 
 displayInfo();

  switch (mainData.mode)
  {
  case 0:
    n1Mode();
    break;
  case 2:
    n2Mode();
    break;
  case 3:
    n3Mode();
    break;
  case 4:
    n4Mode();
    break;
  
  }
  ChangePalettePeriodically();
    
    static uint8_t startIndex = 0;
    startIndex = startIndex + 1; /* motion speed */
    
    FillLEDsFromPaletteColors( startIndex);
    
    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}


void readAcs()      // reading acseleration values from sensor directly to main struct
{
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  mainData.x_acs = a.acceleration.x;
  mainData.y_acs = a.acceleration.y;
  mainData.z_acs = a.acceleration.z;
  return;
}

void readJoy()     // i am filering analog values for better perfomance 
{
  mainData.joyX = (analogRead(JOY_X)+analogRead(JOY_X)+analogRead(JOY_X)+analogRead(JOY_X))/4;
  mainData.joyY = (analogRead(JOY_Y)+analogRead(JOY_Y)+analogRead(JOY_Y)+analogRead(JOY_Y))/4;
  return;
}

void readPot()
{
  mainData.potData = analogRead(POT);
  return;
}

void readButtons()   // buttons : 1) 1; 2)0; 3)1; 4)1;   and mainData.button == 1011 
{
  mainData.button = !digitalRead(A1)*1000+!digitalRead(A2)*100+!digitalRead(A3)*10+!digitalRead(A0);
  return;
}

void sendNRF()
{
  // i am writing telemetri struct only when sending data
  // in this case i can track how relevant telemetri data is

  telemetriData.stable = mainData.stable;
  telemetriData.x_acs = mainData.x_acs;
  telemetriData.y_acs = mainData.y_acs;
  telemetriData.z_acs = mainData.z_acs;

  telemetriData.mode = mainData.mode;
  telemetriData.channel = mainData.channel;

  telemetriData.button = mainData.button;
  
  telemetriData.potData = mainData.potData;
  telemetriData.joyX = mainData.joyX;
  telemetriData.joyY = mainData.joyY;
  radio.write(&telemetriData, sizeof(telemetriData));
}

void sendBL(String inp)
{
  Serial1.print(inp);
  return;
}


// void sendLoRa();

void displayInfo()
{
  display.clearDisplay();
  display.setTextSize(1);             
  display.setTextColor(WHITE);       
  display.setCursor(0, 0);            
  display.print(mainData.channel);    
  display.print("  ");          
  display.print(mainData.mode);
  display.print("  ");
  display.println(mainData.z_acs);      
  display.print(mainData.button);
  display.print("  ");
  display.print(mainData.joyX);
  display.print("  ");
  display.print(mainData.joyX);
  display.print("  ");
  display.println(mainData.potData);
  display.display();
}


void readMode()
{
  bitWrite(mainData.mode, 0, (!digitalRead(A14)));
  bitWrite(mainData.mode, 1, (!digitalRead(A13)));
  bitWrite(mainData.mode, 2, (!digitalRead(A12)));
  bitWrite(mainData.mode, 3, (!digitalRead(A11)));
  bitWrite(mainData.mode, 4, (!digitalRead(A10)));
  bitWrite(mainData.mode, 5, (!digitalRead(A9)));
  bitWrite(mainData.mode, 6, (!digitalRead(A8)));
  bitWrite(mainData.mode, 7, (!digitalRead(A7)));
  return;
}

void readCh()
{
  bitWrite(mainData.channel, 0, !(digitalRead(second_sw[0])));
  bitWrite(mainData.channel, 1, !(digitalRead(second_sw[1])));
  bitWrite(mainData.channel, 2, !(digitalRead(second_sw[2])));
  bitWrite(mainData.channel, 3, !(digitalRead(second_sw[3])));

  bitWrite(mainData.channel, 4, !(digitalRead(second_sw[4])));
  bitWrite(mainData.channel, 5, !(digitalRead(second_sw[5])));
  bitWrite(mainData.channel, 6, !(digitalRead(second_sw[6])));
  bitWrite(mainData.channel, 7, !(digitalRead(second_sw[7])));
  return;
}


void n1Mode()
{
  sendNRF();
  digitalWrite(LED1, !digitalRead(LED1)); // just blink to understand, that it is working
}
void n2Mode()
{

}
void n3Mode()
{

}
void n4Mode()
{

}
void n5Mode()
{

}
void n6Mode()
{

}
void n7Mode()
{

}
void n8Mode()
{

}
void n9Mode()
{

}
void n10Mode()
{

}
void n11Mode()
{

}
void n12Mode()
{

}

void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
    uint8_t brightness = 255;
    
    for( int i = 0; i < NUM_LEDS; i++) {
        leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
        colorIndex += 3;
    }
}

void ChangePalettePeriodically()
{
    uint8_t secondHand = (millis() / 1000) % 60;
    static uint8_t lastSecond = 99;
    
    if( lastSecond != secondHand) {
        lastSecond = secondHand;
        if( secondHand ==  0)  { currentPalette = RainbowColors_p;         currentBlending = LINEARBLEND; }
        if( secondHand == 10)  { currentPalette = RainbowStripeColors_p;   currentBlending = NOBLEND;  }
        if( secondHand == 15)  { currentPalette = RainbowStripeColors_p;   currentBlending = LINEARBLEND; }
        if( secondHand == 20)  { SetupPurpleAndGreenPalette();             currentBlending = LINEARBLEND; }
        if( secondHand == 25)  { SetupTotallyRandomPalette();              currentBlending = LINEARBLEND; }
        if( secondHand == 30)  { SetupBlackAndWhiteStripedPalette();       currentBlending = NOBLEND; }
        if( secondHand == 35)  { SetupBlackAndWhiteStripedPalette();       currentBlending = LINEARBLEND; }
        if( secondHand == 40)  { currentPalette = CloudColors_p;           currentBlending = LINEARBLEND; }
        if( secondHand == 45)  { currentPalette = PartyColors_p;           currentBlending = LINEARBLEND; }
        if( secondHand == 50)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND;  }
        if( secondHand == 55)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; }
    }
}

// This function fills the palette with totally random colors.
void SetupTotallyRandomPalette()
{
    for( int i = 0; i < 16; i++) {
        currentPalette[i] = CHSV( random8(), 255, random8());
    }
}

// This function sets up a palette of black and white stripes,
// using code.  Since the palette is effectively an array of
// sixteen CRGB colors, the various fill_* functions can be used
// to set them up.
void SetupBlackAndWhiteStripedPalette()
{
    // 'black out' all 16 palette entries...
    fill_solid( currentPalette, 16, CRGB::Black);
    // and set every fourth one to white.
    currentPalette[0] = CRGB::White;
    currentPalette[4] = CRGB::White;
    currentPalette[8] = CRGB::White;
    currentPalette[12] = CRGB::White;
    
}

// This function sets up a palette of purple and green stripes.
void SetupPurpleAndGreenPalette()
{
    CRGB purple = CHSV( HUE_PURPLE, 255, 255);
    CRGB green  = CHSV( HUE_GREEN, 255, 255);
    CRGB black  = CRGB::Black;
    
    currentPalette = CRGBPalette16(
                                   green,  green,  black,  black,
                                   purple, purple, black,  black,
                                   green,  green,  black,  black,
                                   purple, purple, black,  black );
}

Комментарии 13

    0
    Отличное начало. Только не стоит ставить невыполнимые цели для такого проекта. Надо брать что-то одно и начинать потихоньку воплощать в жизнь. Так будет всегда подогреваться интерес. А прыжки от одного к другому приведут к тому, что будет куча проектов, и не один не работает. Удачи в обучении.
      0
      Посмотрите в сторону arduino threads. Если продолжить писать в таком стиле (последовательно всё в одном цикле), то с разрастанием программы появятся много разных проблем.
        +1
        Лучше уж чему-то более серьезному тогда учиться, а не костылям для ардуино.
          +1
          Каждой задаче свой инструмент. Если проще и дешевле написать на Ардуино, то почему бы им не воспользоваться? Добавить библиотеку не в сравнении с изучением ЯП.
          Это как к примеру со стриппером, мне он за 10 лет понадобился раз 5 всего, если профессионально не занимаешься протяжкой сетей, то достаточно дешёвого инструмента, просто по той причине, что экономически выгоднее и целесообразнее.
        0
        А почему рука?
          0
          Концепция перчатки для управления чем-то уже была несколько лет. Сначала основной уклон шёл на управление переменными резисторами на пальцах и затем обработки в какой-либо жест (на алиэкспрессе такие штуки есть). Ну а для моих тех роботов необходим был пульт, вот и осуществил давнюю задумку. Конечно не обошлось и без влияния игровой культуры (в частности doom eternal).
            0
            Роботу надо ехать 1 км. прямо.
            Будет держать руку в нужной позиции?

            Какой функционал закладываете?
            Нужно хорошо продумать сценарии работы системы, чтоб потом не менять все.

            п.с.
            Ролик видел. Колесный робот с управлением перчаткой… судя по видео серийная игрушка.
              0
              Роботу надо ехать 1 км. прямо.
              Будет держать руку в нужной позиции?

              Ну работа акселерометра — только доп. фича, это довольно удобно если управлять чем-то маленьким или на местности с препятствиями. В основном тут идёт не прямое управление, а исполнение скриптов, привязанных к определённой кнопке и режиму (например для движения вперёд это будет связка ещё и с потенциометром для изменения расстояния)
              Нужно хорошо продумать сценарии работы системы, чтоб потом не менять все.

              Удобство управления не постоянного, а частичного в том, что я могу сделать сразу множество режимов и посылать на каждом режиме разные команды, которые уже обрабатываются на стороне управляемого робота. Это всё позволит не трогать код программы перчатки и стандартизировать управление, а если так получится сделать, то сценарии работы у каждого робота будут свои.

              Ролик видел. Колесный робот с управлением перчаткой… судя по видео серийная игрушка.

              Всё возможно) Но я делал именно для лёгкости сборки, версия 4 (прошлая) очень трудно и неудобно собирается из-за необходимости пайки навесом множества проводов и всё равно получается, что всё не помещается в маленький корпус. Эта версия перчатки, скорее всего последняя, поэтому хотелось бы, чтобы она была презентабельной.
                0
                Я про удобство использованием оператором.
                + реальные сценарии использования

                п.с.
                Проект же коммерческий по итогу..?
                Ну хотелось бы? ))
                  +1
                  До коммерческого далековато, для запуска его именно в серийное производство придётся вкладывать ещё средства, да и в 10 классе запускать продажи таких устройств не очень легко будет)

                  А так — в планах уже полностью серию Mark пытаться коммерциализировать. Только не как марсоходы (маловато шансов), а как поисково-спасательную систему. У такой системы большое покрытие за счёт маленьких роботов-разведчиков и потенциал к автономности за счёт наличия базы в виде подвижного пункта (Mark 6)
                    0
                    да и в 10 классе


                    Молодец!

                    Зоопарк )) сокращайте.
                    Исходите от реально нужного людям функционала.

                    Летающий, ездящий/ползающий + база. ИМХО

                    п.с.
                    Учитесь на инженера (я не про ИТ), хотя можно и параллельно.
          0
          У меня терпения не хватило печатать на таком же принтере как у вас. Сопло постоянно забивалось, и детали через раз отклеивались от стекла. Пришлось тот заменить на FLYINGBEAR.
            0
            Последнюю робособаку и 3 с 4 версией уже печатал на anycubic kossel linear plus (дельта), а с Anet A8 я печатал преимущественно PLA, сопло редко забивалось, но со временем уже надоело постоянно контролировать весь процесс каждые минут 5 и взял дельту, попутно из фанеры на 10 мм сделал термокамеру. Теперь только иногда приходится его перепрошивать (с чем это связано так и не разобрался, но и на форумах особо информации по поводу моих багов комплексно не было)

            отклеивались от стекла

            Я печатал раньше на малярном скотче. PLA липнет, а ABS пластик тогда не использовал

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое