防止UPSNS-KO“定位器”背部入睡和控制姿势的装置



有一天,我发现那些正在怀孕的女士们在怀孕后期或多或少会有背睡的危险。问题在于,在这种情况下,血管在胎儿的重量之下被挤压,这威胁到非常严重的后果,甚至更多。

因此,我认为对我来说做某种可能阻止它进入这种潜在危险情况的事情可能并不困难。当然,经过很短的时间后,我的眼睛睁开了一个事实,那就是聪明的女人会以一种完全自然的方式规避风险-他们在这些很晚的日子里根本不舒服地仰卧。

但是,不要扔掉已经购买的微控制器,加速度计和让头脑slav恼的出色创意,对吗?

顺便说一下,还有其他动机。从核心选项开始:



最后是一个完全迷人的姿势校正器,说实话,我学到的知识比自己的见解晚。

通常,起初我想要简单而没有多余的装饰,像普通的Occam和普通的剃须刀一样。也就是说,设备应该简单地固定位置,如果在给定时间内没有变化,则应通过振动将该宝贵信息传递给其所有者。选择这样的通知对我来说很自然,因为第二年我一直戴着带有振动警报器的计步器手镯,这是一个奇迹。

当然,我们都知道振动信号并不适合所有人。但是我对通用设备没有任何抱怨-您知道,到处都必须保持合理的平衡。顺便说一句,这就是为什么在最终设计中已经有了我们最喜欢的Arduino环境,许多野蛮的解决方案,甚至是传奇的蓝色(确实是蓝色,水管工带来的)电工胶带。

通常,当我开始磨削未来闹钟的轮廓时,Occam的剃须刀坏了。突然发现了其他潜在的才能,即:姿势控制和警告[办公室浮游生物]行动时间过长。扩展功能的原因很普遍-很遗憾看到即使是最强大但仍然很严重的微控制器的资源也将消失。

怎么运行的


如您所知,定位器具有三种操作模式:

1)防止背部的睡眠(无论是在其他姿势还是其他姿势,对他来说都无所谓)
2)姿势控制
3)行动不便的警告

而且,您仍然不知道,只有一个按钮,它执行复位微控制器的功能。

因此,要选择所需的模式,只需执行以下两项操作即可:按下按钮并将定位器保持在三个位置中的一个(如果有象征意义的话),即位于背面,侧面或站立位置。为了将事物简单地置于待机模式(关闭模拟),您根本不需要做任何事情。也就是说,他们按下了一个按钮,将其放下-定位器进入睡眠状态。

诀窍是什么?选择模式后或安乐死期间,定位器需要保持静止不动,因为在第一种情况下,定位器需要时间来记忆位置,而在第二种情况下,则需要理解到该睡觉了。主要有两个时间间隔:开机后的前五秒用于选择模式,接下来的十秒用于接收位置。

顺便说一下,与此同时,十秒是有条件的概念,因为定位器仅在指定时间内相对位置不变时才记住“坐标”。这样,您就可以选择操作模式并从容地紧贴设备,而不必担心此操作会超时。但是,一上钩,就冻结了10秒钟,以便定位器了解到该开始做生意了。

换句话说,专心的读者已经猜到加速度计的读数是用来选择模式的,而我仍然在树上蔓延。

在这里,您可以看到它在面包板上的原型示例中如何工作:



如您所见,一切都很简单。

在或多或少的最终版本中,警报的工作原理如下:

1)为防止背部出现睡眠,定位器将在约一分钟后触发并通过一系列8个信号唤醒,在任何情况下都不会中断,除了电池放电外。为了让他停止这样做,您应该以不同的方式躺下,等待一系列信号的结束。否则,将重复一系列信号。

2)在姿势控制模式下,定位器可确保从5分钟间隔开始,在大约60%的时间内保持正确的姿势。否则,它会开始振动,直到您恢复正确的姿势。

3)在低移动性警告模式下,定位器确保从30分钟间隔开始至少有8%的时间用于移动。如果不是这样,它将一次产生一系列的10个信号,这些信号不会被中断,而是开始倒数新的间隔。

当然,可以通过按重置按钮来中断任何模式下的警报。

至于间隔和通知可能看起来很奇怪,我从以下内容着手。在我看来,背面的一分钟足够长,并且8个信号没有中断(并且有可能反复接收相同量的信号)似乎足以唤醒。

另一方面,姿势控制不是很关键,因此,首先,不需要100%的控制,其次,梦境中不太可能发生姿势控制,因此,当您返回所需位置时停止的信号就足够了。好吧,一直坐着,好像他已经吞下了阿信一样-有点愚蠢,不太可能。因此,控制间隔是可调的。

最终,当我搜寻必要的最小运动量时,我提到每三小时15-20分钟或多或少就足够了。定位器设置考虑了该信息,但是如果需要,可以在“刷新”微控制器的阶段对其进行修改。同样,没有必要动摇一个人直到失去知觉,因为走或不走是自愿的。因此,只有十个振动信号形式的精致提示。

当然,所有这些间隔都不是教条,可以轻松更改。这将是一种愿望。

定位器由CR2032锂电池供电。睡眠模式(定位器的某些第四伪模式,而不是控制器)的电流消耗为4μA,出于拒绝专用电源开关的考虑,我认为这足以简化设计。在开始时以及直接确定位置时,功耗可能会在不到一秒的时间内超过2 mA,但除信号操作时刻外,功耗通常在1 mA以内。

在两次位置确定之间的间隔中,控制器处于掉电模式,该功耗类似于定位器的睡眠模式-4μA。控制器大约每8秒通过计时器唤醒一次-这是最大程度的节省电池的时间,并且对于所有模式的正确操作或多或少都是可以接受的。



不幸的是,我无法计算出完全的自治权,因为我不知道如何做。

这是怎么做的


首先,一切都超出了我的头脑,其次,即兴演奏,其次是业余活动,因为对我来说,关闭这个姿势比将它提高到绝对程度更有趣。

因此,在将来,我们将牢记我们在谈论一种非常具体且单一的实现。您需要为此:

1)ATtiny85微控制器(例如,此类
2)组装加速度计ADXL335(例如,此类或立即用3.3V电源供电)
3)手机振动电机(我需要大量维修才能修理)
4)按钮(我拿了从分解遥控器)
5)2.2千欧姆电阻器
6)键入1N4007二极管(I有类似KD522
7)NPN晶体管,例如2N2222(我从破损的DVD中取出东西)
8)电池(CR2032)
9)一个合适的情况

该方案如下:在一个非常有趣的ELSE项目中,



我诚实地窃取了有关电动机连接部分

顺便说一句,我强烈推荐Sparkfun提供的如此精美的图片,以至于不能不引用它:



还有另外一个技巧。最重要的是,至少有两个带有ADXL335加速度计的电路板版本:3.3V和最高5V。实际上,加速度计的工作电压范围为1.8V至3.6V,因此第二个版本与第一个版本的区别在于存在稳压器。

。这是一个带有稳定器的(加速度计左侧的三足蟑螂)。照片Tinydeal


。而且这没有稳定剂摄影:Hobby Electronics


。还有一个混合选项-您可以从3.3V单独供电(过去通过稳定器,而在5V时通过稳定器)。照片由Adafruit的


我现在已经与从5V两种工作的稳定,这是不奇怪的董事会,并从3.3V(我检查)。但是由于我没有理由加热稳定器并因此浪费了电池,因此在设备的最终版本中,我绕过了稳定器,直接将加速度计电源直接连接到了它。

。要绕过稳定器,您可以在开发板和ADXL335数据表上浏览


谈论ATtiny85微控制器也不同的事实可能仍然有意义。带有ATtiny85-20类型标记的芯片在商店中最常见且更便宜,而ATtiny85-10则越来越便宜。从制造定位器的角度来看(根据数据表),最重要的区别是ATtiny85-20的工作电压范围为2.7V-5.5V,ATtiny85-10的工作电压范围为1.8V-5.5V。那些。从最充分地利用电池容量的角度来看,第二个更为可取。

第二个差异是20 MHz与10 MHz的时钟频率。尽管对于定位器来说,这通常并不重要:它在1 MHz下工作,并且不会抱怨寿命。但是由于我刚拿到了第一件便宜的东西,所以我只有ATtiny85-20。

最后,如果对某个人还是个谜,我将加速度计连接到了控制器,原因是最容易在定位器的睡眠模式下将其关闭(加速度计)。否则,我们将不断漏出高达350μA的电流(根据ADXL335数据手册)。

他用壁挂式安装装置组装了所有组件,并用搪瓷的0.1毫米漆包线(标有跳线)将元件连接起来,其中一对线圈是好中国人给我的,还有一个焊接站。而我已经一年不知道去哪里了。理想的结果是:用300C烙铁和传统松香将导线完全撕开,并且足够方便地焊接ATtiny85和SOT23封装中的晶体管。

这导致了相当实用的景观:

。什么组件-和设置。一次在B&D精品店中购买一件非常无利可图


算法和代码



定位器工作的基本算法如下:



作为编程环境,我完全选择Arduino作为替代方案,因为现在至少让它做得不好,但我只熟悉它。好吧,我在一开始就提到了格式塔-这也解释了为什么我不学习C ++来制作定位器这一事实。

至于代码,我应该给出一些评论。

基于设备的使用模型(开机并忘记提示,直到忘记),非常需要忘记每天更换电池。为此,您需要认真节省能源,这是非常有可能的,因为ATtiny85数据表中提到的最低消耗量是微安规的十分之一。我必须马上说-我没有上升(或没有下降?)到这样的高度。

在这里,我再次选择了最简单的方法。即-谷歌搜索需要什么。第一个是通过看门狗定时器唤醒使ATtiny85进入最深睡眠模式代码

同时,以毫安为单位的电流消耗下降到数百微安。它已经很漂亮了,但还不够漂亮。

我不得不进一步看。然后事实证明,睡眠是一场梦,需要手动关闭外围设备。同时,即使在睡眠模式下,大部分的能量也会被ADC消耗掉。在这里写

在睡眠期间关闭ADC后,定位器的电源变得和我能用谷歌搜索到的一样和谐。也就是说,正如我在上面所写,在测量过程中唤醒时的最小功耗为4μA-数十或数百微安,而在振动电机运行时,其功耗可能超过2 mA。

可以通过以下事实来估计这种代码混合的可行性:CR2032在定位器中以测试模式工作了一周的时间远没有第一次新鲜。当然,大多数时间是在待机模式下,但活动时间是不错的。简而言之,它接近实际使用模型。

关于使用加速度计的工作。事实是,据我所知,我从绝对值中抽象出来。有几个原因。首先,可以以这种方式更改加速度计,而无需考虑特定硬件的工作原理。其次,对于重言式,我没有铁保证,如果在电池放电过程中不可避免的电压下降,与微控制器中ADC处理相关的加速度计读数不会“浮动”。

最后,将设置放置在变量声明部分中。我就是这么称赞自己的-因为对定位器进行微调,您不必查找所有代码并在搜索需要替换值的所有片段时用不好的话记住我。

根据通用说明,代码已通过Arduino Mega上传到ATtiny85。那些。首先在这里下载了针对其Arduino环境版本的ATtiny支持

然后,像往常一样,他将档案文件的内容(包含所有内容的小目录)解压缩到他的Arduino目录的硬件文件夹中:



然后我进入该目录,并根据说明制作了boards.txt文件,从现有文件中复制了Prospective Boards.txt我需要的-即 ATtiny 1 MHz的描述,以防万一,为8 MHz。

这是boards.txt
attiny85at8.name=ATtiny85 @ 8 MHz  (internal oscillator; BOD disabled)

# The following do NOT work...
# attiny85at8.upload.using=avrispv2
# attiny85at8.upload.using=Pololu USB AVR Programmer

# The following DO work (pick one)...
attiny85at8.upload.using=arduino:arduinoisp
# attiny85at8.upload.protocol=avrispv2
# attiny85at8.upload.using=pololu

attiny85at8.upload.maximum_size=8192

# Default clock (slowly rising power; long delay to clock; 8 MHz internal)
# Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms; [CKSEL=0010 SUT=10]; default value
# Brown-out detection disabled; [BODLEVEL=111]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]

attiny85at8.bootloader.low_fuses=0xE2
attiny85at8.bootloader.high_fuses=0xD7
attiny85at8.bootloader.extended_fuses=0xFF
attiny85at8.bootloader.path=empty
attiny85at8.bootloader.file=empty85at8.hex

attiny85at8.build.mcu=attiny85
attiny85at8.build.f_cpu=8000000L
attiny85at8.build.core=tiny
 
###########################################################################
###########################################################################

attiny85at1.name=ATtiny85 @ 1 MHz  (internal oscillator; BOD disabled)

# The following do NOT work...
# attiny85at1.upload.using=avrispv2
# attiny85at1.upload.using=Pololu USB AVR Programmer

# The following DO work (pick one)...
attiny85at1.upload.using=arduino:arduinoisp
# attiny85at1.upload.protocol=avrispv2
# attiny85at1.upload.using=pololu

attiny85at1.upload.maximum_size=8192

# Default clock (slowly rising power; long delay to clock; 8 MHz internal; divide clock by 8)
# Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms; [CKSEL=0010 SUT=10]; default value
# Divide clock by 8 internally; [CKDIV8=0]
# Brown-out detection disabled; [BODLEVEL=111]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]

attiny85at1.bootloader.low_fuses=0x62
attiny85at1.bootloader.high_fuses=0xD7
attiny85at1.bootloader.extended_fuses=0xFF
attiny85at1.bootloader.path=empty
attiny85at1.bootloader.file=empty85at1.hex

attiny85at1.build.mcu=attiny85
attiny85at1.build.f_cpu=1000000L
attiny85at1.build.core=tiny
 
###########################################################################
###########################################################################



之后,我启动了Arduino,确保必要的ATtiny出现在“服务-板”菜单中:我



连接了(当然,选择了正确的板)Arduino Mega 2560,并从示例中将Arduino ISP草图写入其中:



然后,我根据Mega 2560引脚连接将ATtiny连接到Mega 和Arduino ISP草图中的说明:

// pin name:    not-mega:         mega(1280 and 2560)
// slave reset: 10:               53 
// MOSI:        11:               51 
// MISO:        12:               50 
// SCK:         13:               52 


当然,我将ATtiny连接到电源和地面,在我的情况下,两条线都与程序员共享,即 Mega 2560,尽管我们都知道总数的必要最小值是SPI,复位和接地线。

当一切准备就绪后,首先(不要忘记选择ATtiny85板),引导程序写道:



在他之后-实际上是草图
// 
// http://donalmorrissey.blogspot.ru/2010/04/sleeping-arduino-part-5-wake-up-via.html
// http://www.technoblogy.com/show?KX0

/* 
 . 			
 - . 		
 - ..		
 - ...		
 - 			    
 ...			 
 --			, 
 .......... 	
 */


#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

volatile int f_wdt=1;

#define xPin A1 //   X
#define yPin A2 //   Y
#define zPin A3 //   Z
#define alPin 0 //   
#define posPowPin 1 //   
#define timeLimit 10000 //    
 #define posCountSleep 9 //      (*8 ) 8
#define posCountMove 231 //      (*8 ) 230
#define posCountBack 41 //      40
#define tresholdSleep 25 //     
#define tresholdMove 25 //    
#define tresholdBack 20 //     
#define movPercentMove 92 //   ( %)   
#define movPercentBack 40 //    ( %)   
#define startTimeOut 5000//         
#define motionTimeOut 1500//        

unsigned long timeOut; //    
byte treshold = 15; //    
int posCounter = 1; //    
byte posMode = 0; //   (  -  = 0;    - 1;  - 2;  - 3)
int posTolerance = 0; //         ( 009b).
int x, y, z, x1, y1, z1; // 
int relX, relY, relZ; //    
int posCount; //     
boolean alarmRaised = false; //  
boolean standBy = false; //    

// http://www.technoblogy.com/show?KX0
#define adc_disable() (ADCSRA &= ~(1<<ADEN)) // disable ADC (before power-off) 
#define adc_enable()  (ADCSRA |=  (1<<ADEN)) // re-enable ADC

ISR(WDT_vect)
{
  if(f_wdt == 0)
  {
    f_wdt=1;
  }
}

void enterSleep(void)
{
  pinMode(alPin, INPUT);
  pinMode(posPowPin, INPUT);

  adc_disable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  

  sleep_enable();

  sleep_mode();

  sleep_disable(); 

  power_all_enable();
  adc_enable();

  pinMode(alPin, OUTPUT);
  digitalWrite(alPin, LOW);

  pinMode(posPowPin, OUTPUT);
  digitalWrite(posPowPin, LOW);
}


void setup() {

  /*** Setup the WDT ***/

  /* Clear the reset flag. */
  MCUSR &= ~(1<<WDRF);

  /* In order to change WDE or the prescaler, we need to
   * set WDCE (This will allow updates for 4 clock cycles).
   */
  WDTCR |= (1<<WDCE) | (1<<WDE);

  /* set new watchdog timeout prescaler value */
  WDTCR = 1<<WDP0 | 1<<WDP3; /* 8.0 seconds */

  /* Enable the WD interrupt (note no reset). */
  WDTCR |= _BV(WDIE);

  //   
  pinMode(alPin, OUTPUT);
  digitalWrite(alPin, LOW);

  //   
  pinMode(posPowPin, OUTPUT);
  digitalWrite(posPowPin, LOW);

  pinMode(xPin, INPUT);
  pinMode(yPin, INPUT);
  pinMode(zPin, INPUT);

  delay(1000); // -
  blinker(500, 1); //   

  if (motionDetect(startTimeOut) == true) {

    getPos(); //  	

    if (abs(x1-y1) > abs(x1-z1)) {
      if (abs(x1-z1) > abs(y1-z1)) {
        selectX(); // x
      } 
      else {
        posMode = 2; // y
        posCount = posCountMove; //   
        treshold = tresholdMove;		
        blinker(1000, 1);
        blinker(500, 2);  
      }
    } 
    else {
      if (abs(x1-y1) > abs(z1-y1)) {
        selectX(); //x
      } 
      else {
        posMode = 1; // z
        posCount = posCountSleep; //    		
        treshold = tresholdSleep;
        blinker(1000, 1);
        blinker(500, 1);    
      }
    }
  }

  if (posMode > 0) {

    getPos(); //  
    x = x1; //  
    y = y1;
    z = z1;
    timeOut = millis();	

    while ((millis() - timeOut) < timeLimit) {
      getPos();
      if (comparePos(x, y, z, x1, y1, z1) == false) { //    -  
        blinker(1000, 1); //    
        x = x1; 
        y = y1; 
        z = z1;
        timeOut = millis();
      }
    }

    //       
    standBy = true;
    blinker(500, 3); //   
  }
  else {
    blinker(1500, 2);
  }	


}

void loop() {

  if(f_wdt == 1) {

    if (posMode == 0) {
      /* Don't forget to clear the flag. */
      f_wdt = 0;

      /* Re-enter sleep mode. */
      enterSleep();
    }
    else {

      getPos();

      if (posCounter <= posCount && alarmRaised == false) { //          
      
      if (posMode == 2) { //    
        if (motionDetect(motionTimeOut) == true) { //      
          posTolerance = posTolerance++; //   
        }

        if ((posCounter - posTolerance) > (posCount*movPercentMove)/100) { //      %   
          alarmRaised = true; //   
        } 

      } else { //   
          if (comparePos(x, y, z, x1, y1, z1) == true) { //    
            posTolerance = posTolerance++; //   ""  (       )
          }
        }
      
        
        if (posMode == 1) { //   
          if (posTolerance >= (posCount - 1)) { //     
            alarmRaised = true; //   
          } 
        }

        if (posMode == 3) { //    
          if ((posCounter - posTolerance) > (posCount*movPercentBack)/100) { //       %   
            alarmRaised = true; //   
          } 
        }

       posCounter++;

      } 
      else { //    

       posCounter = 1; //   
       posTolerance = 0;
       
      }

      if (alarmRaised == true) { //   

        if (posMode == 1) { //   
          blinker(500, 8); // 8  ...
          getPos(); 
          if (comparePos(x, y, z, x1, y1, z1) == false) { // ... 
            alarmRaised = false; //  
            posCounter = 0;
          }
        }

        if (posMode == 2) { //   
          blinker(500, 10); // 10 
          alarmRaised = false; //   
          posCounter = 0;
        } 

        if (posMode == 3) { //   
          blinker(500, 1); //    ...
          getPos();
          if (comparePos(x, y, z, x1, y1, z1) == true) { // ...  
            alarmRaised = false; //   
            posCounter = 0;
          }
        }
        
        posTolerance = 0; //    
      } 
      else {
        /* Don't forget to clear the flag. */
        f_wdt = 0;

        /* Re-enter sleep mode. */
        enterSleep();
      }
    } // posMode == 0
  } // wdt
} // loop

// 

void blinker(unsigned int impulse, byte times) {

  for (byte ttimes = 0; ttimes < times; ttimes++) {

    digitalWrite(alPin, HIGH);
    delay(impulse);
    digitalWrite(alPin, LOW);
    delay(impulse);

  }

}


//     
boolean comparePos(int xOne, int yOne, int zOne, int xTwo, int yTwo, int zTwo) {

  boolean compareRes = false;

  relX = xOne - xTwo;
  relY = yOne - yTwo;
  relZ = zOne - zTwo;

  if (abs(relX) < treshold && abs(relY) < treshold && abs(relZ) < treshold) {
    compareRes = true; //      
  }
  return compareRes;

}

boolean motionDetect(int detectTimeOut) {
 
  boolean motionDetected = false;
  
  getPos();
  x = x1; y = y1; z = z1; //   ,       ,    
  timeOut = millis();
  
  while (((millis() - timeOut) < detectTimeOut)) { //    detectTimeOut ,       
   if (motionDetected == false) { //    
    if (comparePos(x, y, z, x1, y1, z1) == false) { //     
      motionDetected = true; //   
    } 
    else {
      getPos();
    }
   }
  }
  
  return motionDetected;
}

//   
void getPos(){

  digitalWrite(posPowPin, HIGH);
  delay(10);

  byte i;
  unsigned int posX = 0;
  unsigned int posY = 0;
  unsigned int posZ = 0;

  for (i = 0; i < 100; i++) {
    posX = posX + analogRead(xPin);
    posY = posY + analogRead(yPin);
    posZ = posZ + analogRead(zPin);
  }

  x1 = posX/100;
  y1 = posY/100;
  z1 = posZ/100;

  digitalWrite(posPowPin, LOW); 
}

void selectX() {
  posMode = 3;
  posCount = posCountBack; //   		
  treshold = tresholdBack;
  blinker(1000, 1);
  blinker(500, 3);
}






住房


从一开始,我就没有幻想过必须从头开始从头完成此案。我很快拒绝的第一个想法是要得到一个装有几块胶合聚苯乙烯板的盒子。由于材料的足够高的强度和刚度,这将是可悲的-就像瑞士手表的排版表壳一样-并且非常可靠。

但是,我从指定的聚苯乙烯(仅1.5毫米厚)上切下了第二种Eulampia的盖子后,我的热情消失了一点。事实证明这很困难-仅用一把地毯刀将聚苯乙烯切掉。

因此,当另一种照明发生时,我感到非常高兴-您需要取容易形成所需形状的聚合物黏土,然后烘烤直至固体。更准确地说,在我看来是这样,因为我没有考虑到一个重要的细节:我知道环氧树脂没有硬化,聚合物粘土没有特别好地硬化。但这是歌词。

我以最紧凑的方式分解了组件,估算了车身的尺寸,并制作了相应形式的纸板模板,并用聚合物粘土填充了它。然后,他在仍然较软的物体上切出必要的孔,并按照说明进行烘烤。然后持续相同的时间,因为粘土不想硬化。

顺便说一句,电池开一个直径稍大的孔是合乎逻辑的,因此,在研究俄罗斯银行网站后,我发现10卢布硬币很适合这种作用,由于直径为22毫米,自2010年以来就铸造了。仅有一点余量,CR2032才能正常落入电池盒中,我很早就从弹簧上装有一个触点,该触点早已从其他电池盒中取出。

当然,我也借用了电池仓的设计,因为我几乎无法想出更好的东西,这消除了倒车时的头痛。

。这样的事情在过程中


。所以在我不得不拆开已经粘着的身体之后


就是说,一切都非常简单:我连接了组件,将其轻轻按下,然后将其删除-沿轮廓将其切出。好吧,再加上发布的广告位和渠道。有什么好处:定位器上放了一块很小的粘土。自然,我买了最小的一包57包,但我仍然有50克这种有价值的原料。这是第一个。第二:为了不影响静止塑料布局的几何形状,您可以烘烤它而不必将其从纸板上移开,因为所需的温度是100C-110C,即远离纸火。

在箱子的框架以某种方式烘烤后,用刀将其边缘稍微修剪一下。在尝试了这些成分之后,我发现这种#$%&*#粘土不仅没有像应有的那样硬化,而且在烘烤过程中也被“油炸”了。因此,我不得不小心地扩大切口。幸运的是,所得材料不是石头。

上壁和下壁的问题借助于塑料卡的碎片得以解决,该塑料卡与半毫米的聚苯乙烯不同,可以用简单的剪刀完美地切割。我立即固定了底壁(顶部也是如此,但徒劳),但最后我的行为与顶部不同。即:将其放在框架上并小心地将所得结构包装到热缩管中。这种方法的优点是,如有必要,可以轻松拆卸所有零件以进行防水密封,并且同样易于重新组装。

。令人心碎的眼镜




好吧,看-他怎么了?无论如何,我将要为定位器制作一个纺织箱,因为这对于该装置是最合理的,理论上是可以睡觉的。这种情况只会改善外观和触感。

顺便说一句,如果您遵循我的脚步,我不建议您使用白色收缩:虽然很优雅,但是会很快变脏。

为什么不在3D打印机上打印?首先,我没有它。和业主不知道。其次,我不知道如何绘制模型。第三,由于我首先计划了30x70毫米的框架,所以我将不得不打印很多东西,在此过程中,它变成了宽度小于30毫米,长度约为65毫米的框架。此外,在还没有时间掌握的黏土中,我设法切开了按钮的凹口,这是我最初忘记的。

并每次重新上胶。尽管我没有争论,但它比我的Redneck 3D建模版本要酷得多。

免责声明


首先,我想说的是,定位器不仅与医疗设备没有丝毫关系,甚至与月亮有关的膳食补充剂也没有任何关系。这是一个实验。这是对懒惰和无聊的一种逃避。这是尝试用自己的双手发明并执行类似操作的尝试。

因此,当然不能将其视为救生员或类似的东西。有趣的同伴,助手-是的。而且,当然可以故意欺骗它,但是有可能-不是故意欺骗。特别是如果选择固定位置是错误的。

例如,为防止背部出现睡眠,定位器应作好准备,固定在身体其余部分刚打开的那部分身体上。而且,在控制移动性时,最好将定位器放在身体最易移动的部位,尽管我检查过他是否能很好地适应牛仔裤时口袋中的当前设置。好吧,如果要摆姿势,则需要固定定位器,以便如果您弯曲了,那么他就在这个弯曲的部分。

否则,无济于事。

我同意可以使用另一个控制器和另一个加速度计,也可以拥有更多的C ++,并且更多的是用我自己的大脑……所以我不禁止-尝试一下。我相信你会比我更好。

实际上,这就是为什么我写Geek而不是Habré的原因。可以这么说,为了妥协,后者实际上是第一个。

Source: https://habr.com/ru/post/zh-CN381771/


All Articles