MicroPython Examples

Must Watch!



MustWatch

6-axis motion tracking device MicroPython Wiki MicroPython tutorial for ESP8266 MicroPython-Examples micropython-samples BBC micro MicroPython Programming Hardware in Python

LED

A light-emitting diode (LED) is a semiconductor device that emits visible light when an electric current passes through it. The light is not particularly bright, but in most LEDs it is monochromatic, occurring at a single wavelength. The output from an LED can range from red (at a wavelength of approximately 700 nanometers) to blue-violet (about 400 nanometers). Some LEDs emit infrared (IR) energy (830 nanometers or longer); such a device is known as an infrared-emitting diode (IRED).

Schematic

Code

from machine import Pin from time import sleep # GPIO16 (D0) is the internal LED for NodeMCU led = Pin(16, Pin.OUT) # The internal LED turn on when the pin is LOW while True: led.high() sleep(1) led.low() sleep(1)

Here is the reason why the built in led turn on when Pin 16 is Low :)

Toggle a LED

def led_toggle(): led.value(not led.value())

Now we can use this function to blink the LED

while True: led_toggle() sleep(1)

Button

Schematic

Code

from machine import Pin from time import sleep led = Pin(16, Pin.OUT) button = Pin(14, Pin.IN, Pin.PULL_UP) while True: # The value function returns the current level of the pin, # either 1 for a high logic level or 0 for a low logic level. # Notice how the button is at a high level (value returns 1) when # it's not pressed. This is because the pull-up resistor keeps the pin at # a high level when it's not connected to ground through the button. # When the button is pressed then the input pin connects to ground # and reads a low level (value returns 0). if not button.value(): # Remember that the internal led turn on # when the pin is LOW led.low() else: led.high() sleep(.1)

Pull Up resistor

With a pull-up resistor, the input pin will read a high state when the button is not pressed. In other words, a small amount of current is flowing between VCC and the input pin (not to ground), thus the input pin reads close to VCC. When the button is pressed, it connects the input pin directly to ground. The current flows through the resistor to ground, thus the input pin reads a low state.

Here is a good explanation about this circuit.

Toggle a LED

def led_toggle(): led.value(not led.value()) while True: if not button.value(): led_toggle() time.sleep(.5)

NeoPixels

NeoPixels, also known as WS2812b LEDs, are full-colour LEDs that are connected in serial, are individually addressable, and can have their red, green and blue components set between 0 and 255. They require precise timing to control them and there is a special neopixel module to do just this.

Schematic

NeoPixel basics

To create a NeoPixel object do the following:

>>> from machine import Pin >>> from neopixel import NeoPixel >>> np = NeoPixel(Pin(14), 8)

This configures a NeoPixel strip on GPIO14 with 8 pixels. You can adjust the “14” (pin number) and the “8” (number of pixels) to suit your set up.

>>> for i, pixel in enumerate(np): ... print(i, pixel) ... ... ... 0 (0, 0, 0) 1 (0, 0, 0) 2 (0, 0, 0) 3 (0, 0, 0) 4 (0, 0, 0) 5 (0, 0, 0) 6 (0, 0, 0) 7 (0, 0, 0)

To set the colour of pixels use:

>>> np[0] = (255, 0, 0) # set to red, full brightness >>> np[1] = (0, 128, 0) # set to green, half brightness >>> np[2] = (0, 0, 64) # set to blue, quarter brightness

Then use the write() method to output the colours to the LEDs:

>>> np.write()

To set a random color you can use the getrandbits() function

>>> from urandom import getrandbits >>> for i in range(np.n): ... np[i] = (getrandbits(8), getrandbits(8), getrandbits(8)) ... ... ... >>> np.write()

Demo

Go to the examples/neopixels/src/python folder and upload the main.py with ampy:

$ bin/ampy --port /dev/ttyUSB0 put main.py

Then go to the python shell, reboot MicroPython with Ctrl-D (to load the main.py file) and run the function demo(pin, n), where pin is the GPIO number and n is the length of pixels in the neopixels array.

$ bin/shell [Ctrl-D] PYB: soft reboot #21 ets_task(40100164, 3, 3fff8398, 4) could not open file 'boot.py' for reading MicroPython v1.8.7-7-gb5a1a20a3 on 2017-01-09; ESP module with ESP8266 Type "help()" for more information. >>> demo(pin=14, n=8)

Resources

DHT11

The DHT11 is a temperature and humidity sensor.

Schematic

The basic code is

>>> from machine import Pin >>> from dht import DHT11 >>> d = DHT11(Pin(14)) >>> d.measure() >>> d.temperature() 28 >>> d.humidity() 16

Logging the data with Phant

Download the server

$ sudo npm install -g phant

Start the server

$ phant phant http server running on port 8080 phant telnet server running on port 8081

Go to the browser and open the http://localhost:8080, then click on Create a data stream. Complete the Title with "ESP8266 Weather" and the Description with "ESP8266 Weather Station" for the new data stream and put the following fields: temperature and humidity. Then save and copy the public and private key (or download the keys as a JSON file).

Making http requests with urequests

MicroPython has urequest which is very small port from the Python Requests lib.

According the Phant documentation the curl to send data is:

$ curl -X POST 'http://PHANT_HOST/input/PUBLIC_KEY' \ -H 'Phant-Private-Key: PRIVATE_KEY' \ -d 'temperature=24.1&humidity=40.2'

So to get this with urequest you have to do the following

import urequests url = 'http://%s/input/%s?temperature=24.1&humidity=40.2' % (PHANT_HOST, PUBLIC_KEY) headers = {'Phant-Private-Key': PRIVATE_KEY} response = urequests.post(url, headers=headers)

You can check the response code and reason as following

print(response.status_code, response.reason)

See the full code here

Install the code

Go to the examples/dht11/src/python folder and update the boot.py file with your WiFi essid and password, and the main.py file with the Phant host and keys. Then upload the files with the ampy tool, using the script:

$ bin/put.sh

Then open the Python shell, reboot MicroPython (to load the files) and run the following

$ bin/shell [Ctrl-D] ... >>> data = read_sensor() >>> phant_log(data)

There is a function run() to do this endless

while True: data = read_sensor() print("Sending data", data) phant_log(data) time.sleep(60)

Phant interface

Visualize the data

You can make graphs with Google Charts, just open the html/weather.html example file changing the phant_host and public_key variables according to your settings.

SDD1306

The SDD1306 is a driver for Oled Displays.

Get the library and upload

$ wget https://raw.githubusercontent.com/adafruit/micropython-adafruit-ssd1306/master/ssd1306.py $ ampy -p /dev/ttyUSB0 put ssd1306.py

Then check the files on the esp

$ ampy -p /dev/ttyUSB0 ls boot.py ssd1306.py

Now, lets play

>>> from machine import Pin, I2C >>> i2c = I2C(scl=Pin(5), sda=Pin(4)) >>> from ssd1306 import SSD1306_I2C >>> oled = SSD1306_I2C(128, 64, i2c) >>> oled.fill(1) >>> oled.show() >>> oled.fill(0) >>> oled.show() >>> oled.pixel(0, 0, 1) >>> oled.show() >>> oled.pixel(127, 63, 1) >>> oled.show() >>> oled.text('Hello', 0, 0) >>> oled.text(‘World’, 0, 10) >>> oled.show() >>> oled.invert(True) >>> oled.invert(False)

SDCard

Ref: Adafruit - MicroPython Hardware: SD Cards

Download the sdcard.py module. Next use a tool like ampy to copy the sdcard.py file to the root of the board's filesystem:

$ ampy --port /dev/ttyUSB0 put sdcard.py

Mount SD Card:

>>> import machine, sdcard, os >>> sd = sdcard.SDCard(machine.SPI(1), machine.Pin(15)) >>> os.umount() >>> os.VfsFat(sd, "") >>> os.listdir() ['somefile']

Then write a file

>>> f = open('test', 'w') >>> f.write('hello world') 11 >>> f.close() >>> os.listdir() ['somefile', 'test']

Then read a file

>>> f = open('test', 'r') >>> f.read() 'hello world' >>> f.close()

OTA

Over-The-Air (OTA) update is the wireless delivery of new firmware.

There is still not OTA for MicroPython, but will be under development soon. Check this https://www.kickstarter.com/projects/214379695/micropython-on-the-esp8266-beautifully-easy-iot/posts/1540979

But you can do OTA with C++ as described in the C++ OTA section of this wiki.

AP

You can put the esp8266 as an Access Point mode with the following lines

import network ap = network.WLAN(network.AP_IF) ap.config(essid="ESP-AP", password="12345678") ap.active(True)

RGB Lamp

PWM (Pulse With Modulation)

Pulse width modulation (PWM) is a way to get an artificial analog output on a digital pin. It achieves this by rapidly toggling the pin from low to high. There are two parameters associated with this: the frequency of the toggling, and the duty cycle.

See the micropython doc here.

import socket import machine import template ADDR = ('0.0.0.0', 80) PIN_R = 12 PIN_G = 13 PIN_B = 14 class RGBLed: def __init__(self, pin_r, pin_g, pin_b): self.pin_r = machine.PWM(machine.Pin(pin_r)) self.pin_g = machine.PWM(machine.Pin(pin_g)) self.pin_b = machine.PWM(machine.Pin(pin_b)) self.set(0, 0, 0) def set(self, r, g, b): self.r = int(r) self.g = int(g) self.b = int(b) self.duty() def duty(self): self.pin_r.duty(self.duty_translate(self.r)) self.pin_g.duty(self.duty_translate(self.g)) self.pin_b.duty(self.duty_translate(self.b)) def duty_translate(self, n): """translate values from 0-255 to 0-1023""" return int((float(n) / 255) * 1023) def get_url(conn): conn_file = conn.makefile('rb', 0) method, url = None, None while True: line = conn_file.readline().decode() if not line or line == '\r\n': break if line.startswith('GET'): method, url, _ = line.split() return method, url def parse_url(url): try: path, query = url.split('?', 2) except: return url, {} return path, {_.split('=')[0]: _.split('=')[1] for _ in query.split('&')} def conn_send(conn, response): total_sent = 0 while total_sent < len(response): sent = conn.send(response[total_sent:]) if sent == 0: raise RuntimeError('Socket connection broken') total_sent = total_sent + sent led = RGBLed(PIN_R, PIN_G, PIN_B) s = socket.socket() s.bind(ADDR) s.listen(1) print('RGBLamp daemon started on %s:%s' % ADDR) while True: conn, addr = s.accept() method, url = get_url(conn) path, query = parse_url(url) print(addr[0], '-', method, url) if path == '/': if [_ for _ in list('rbg') if _ in query.keys()]: led.set(query.get('r', 0), query.get('g', 0), query.get('b', 0)) response = template.html % (led.r, led.g, led.b) conn_send(conn, response) conn.close()

Servo sg90

The sg90 servo has three wires: brown (gnd), red (vcc), and yellow (signal). The vcc is the power source for the servo, and it has to be connected to the vin pin of our board – this way it is connected directly to the USB port, and not powered through the board.

The signal wire tells the servo what position it should move to, using a 50Hz PWM signal. The center is at around 77, and the exact range varies with the servo model, but should be somewhere between 30 and 122, which corresponds to about 180° of movement. Note that if you send the servo a signal that is outside of the range, it will still obediently try to move there – hitting a mechanical stop and buzzing loudly. If you leave it like this for longer, you can damage your servo, your board or your battery, so please be careful.

So now we are ready to try and move it to the center position:

from machine import Pin, PWM servo = PWM(Pin(14), freq=50, duty=77)

Then we can see where the limits of its movement are:

servo.duty(30) servo.duty(122)

Ref: http://micropython-on-esp8266-workshop.readthedocs.io/en/latest/basics.html#servomechanisms

使用MicroPython从ESP板发送数据到Google表格

esp32 sending data to google sheets Google表格提供了很棒的HTTP API,为什么我们不能只发送一个POST请求来将数据插入到工作表中? 原因是Google表格API关注安全性并需要身份验证。 特别是,Google Sheet API支持两种身份验证方法:API密钥和OAuth2令牌。 使用API密钥听起来很简单: 我们可以在Google IAM控制台中创建一个API密钥,在我们的ESP板上编码,忘记旋转密钥和安全性,并永远使用密钥。 不幸的是(或者说幸运的是)它不会起作用。 Google Sheet API仅允许API键进行读取操作。 如果要写入工作表,则必须使用OAuth2。这里出现了问题。 首先,您需要在Google IAM控制台中创建一个服务帐户,然后为该服务帐户创建一个私有RSA密钥。 好的,那并不难。 然后,您的ESP板必须构建一个JWT请求,将当前时间戳放入其中,并使用RSA-SHA256签名算法使用密钥对请求进行签名。 接下来,板子必须将签名的JWT请求发送到Google OAuth2服务,该服务最终返回OAuth2令牌。 最后使用令牌来调用Google表格API。 让我快速总结一下ESP板能够在Google表格中插入一行需要的内容: HTTP客户端、JSON解析器、具有正确时间的实时时钟或NTP客户端,以及RSA-SHA256签名的实现算法。 幸运的是,MicroPython提供了除RSA-SHA256签名之外的大部分内容。 确切地说,MicroPython可以计算SHA256哈希,但不能使用RSA算法对数据进行签名。 此外,RSA签名是一项昂贵的操作,可能需要相当多的时间和内存,但ESP板并不像PC那么强大,也没有太多的内存。 我猜想Google身份验证带来的复杂性以及缺少MicroPython的RSA,让人们使用了一个公开的表单或一个可以实现认证过程的中间件服务。 当然,作为一名安全工程师,我无法接受一个包含公共可用表格的解决方案,其中包含我房间内温度和湿度等敏感数据。 因为我是一名安全工程师,所以我不喜欢中间件。 最后,唯一的选择是以某种方式在ESP板上实现上述认证过程。 正如我之前提到的,MicroPython已经提供了大部分必需的东西: ujson允许解析JSON ntptime.py提供NTP客户端 uhashlib可以计算SHA256哈希值 http.client提供了一个HTTP客户端 唯一缺少的部分是RSA签名。 密码学的一个主要规则是:不要自己实现任何加密算法,而是使用现有的算法。 我知道这个规则,并发现python-rsa包在纯Python中实现了RSA算法。 除了使用RSA进行签名之外,该库还支持其他操作,例如验证签名,加密和解密,加载和存储密钥等。 这个库对于一个小型的ESP板来说负担太重了,我决定只保留RSA签名的实现并删除剩下的代码。 我甚至删除了以PKCS1格式加载RSA密钥的代码,因为它需要移植一个不小的pyasn1包。 我还必须基于从右到左的二进制方法和其他一些操作来实现模块化求幂,因为事实证明它们不是由MicroPython提供的。 它产生了一个新的micropython-rsa签名库。 我使用ESP8266和MicroPython以前的一个项目作为起点。 在实施身份验证过程并在我的笔记本电脑上进行测试后,我终于成功用ESP8266主板运行了代码。 不幸的是我发现代码运行得很慢,主要问题是ESP8266主板没有足够的内存来完成RSA签名。 我尝试了一些优化,甚至尝试将应用程序代码嵌入到MicroPython固件中,但没有任何帮助。 最后的希望是在ESP32上运行代码。 我之前没有用过ESP32,于是订购了我的第一个ESP32开发板。 幸运的是,它成功了! 应用程序不再抱怨内存不足,事实上它运行得更快了。 该代码可在GitHub上获得。 README简要描述了如何构建项目。 我还在Hackaday.io上创建了一个项目。 我希望我能找到一些时间在后续帖子中提供更多细节。 https://github.com/artem-smotrakov/esp32-weather-google-sheets

timers_and_interrupts_timer

from machine import Pin, Timer led = Pin(5, Pin.OUT) led.value(0) timer = Timer(-1) timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:led.value(not led.value()))

timers_and_interrupts_interrupt

from machine import Pin led = Pin(5, Pin.OUT) button = Pin(4, Pin.IN, Pin.PULL_UP) button.irq(trigger=Pin.IRQ_FALLING, handler=lambda t:led.value(not led.value()))

timers_and_interrupts_debounce

from machine import Pin led = Pin(5, Pin.OUT) button = Pin(4, Pin.IN, Pin.PULL_UP) def debounce(pin): prev = None for _ in range(32): current_value = pin.value() if prev != None and prev != current_value: return None prev = current_value return prev def button_callback(pin): d = debounce(pin) if d == None: return elif not d: led.value(not led.value()) button.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)

Pwm and Adc with a Nodemcu and Micropython

https://micronote.tech/2020/02/PWM-and-ADC-with-a-NodeMCU-and-MicroPython/ from machine import Pin, PWM, ADC, Timer POT_LOWER_EXTREME = 18 POT_UPPER_EXTREME = 1024 pwm_led = PWM(Pin(5), freq=1000) pot = ADC(0) def pot_percent(val, lower_limit, upper_limit): if val > upper_limit: val = upper_limit elif val < lower_limit: val = lower_limit total_range = upper_limit - lower_limit return (val-lower_limit)/total_range def set_dimmer(pin): pwm_led.duty(int(pot_percent(pot.read(), POT_LOWER_EXTREME, POT_UPPER_EXTREME) * 1023)) timer = Timer(-1) timer.init(period=100, mode=Timer.PERIODIC, callback=set_dimmer)

6 axis

6axis Robotic-Arm-Raspberry RobotControl Smoothieboard can be made to work for more than 3 axes. We are not talking about extruders here ( these are supported separately, see Extruder ), but rotational axes, like those for example used for 4 or 5 axis machining. This feature is one of the rare ones that requires compiling Smoothie. Because it increases the size of the movement planning queue significantly, we were unfortunately not able to fit it in the “normal” firmware. There are two resources that were written about this feature when it was released that you might want to read : ABC pull request on github. Smoothie's upgrade notes

Workpiece Coordinate System

NOTE that currently WCS is not supported for ABC axis (G10 L2…). G92 A0 resets the A axis and does not set the WCS for it (same for B and C).

Extruders

NOTE You cannot define extruders AND ABC axis they are mutually exclusive and smoothie will not run if they are both defined.

Compiling 6 axis.

Before attempting this, please read compiling smoothie, and compile Smoothie “normally” for practice. Once that is done ( and only once that is done ), you need to do the same process, but instead of doing make You now do : make clean make AXIS=6 CNC=1 You can change this number to 5 or 4 if you do not need all 6 axes. It saves memory and allows you to use more of it for other things. By default, Smoothie calculates distances only on the first three ( XYZ ) axes. You can change this behavior by setting the PAXIS compilation parameter, for example: make AXIS=5 PAXIS=4 CNC=1 Means Smoothie is compiled with XYZAB axes, and distances are calculated in the XYZA space.

Primary Axes

NOTE that in most cases you DO NOT need to set PAXIS. Only do this if you fully understand the difference between a Cartesian (primary) axis and say a rotary axis. Once your firmware is compiled, you can now flash it to the board and start using it.

Using additional axes

XYZ first

NOTE You MUST fully define the alpha, beta and gamma (XYZ) axis before the other axis. They MUST have valid pin definitions for the step and dir pins (enable is optional) If you do not define valid pins for these first three axis smoothie will not boot. You can now add the following to your configuration file : # A axis delta_steps_per_mm 100 # may be steps per degree for example delta_step_pin xx # Pin for delta stepper step signal delta_dir_pin xx # Pin for delta stepper direction delta_en_pin xx # Pin for delta enable delta_current 1.5 # Z stepper motor current delta_max_rate 300.0 # mm/min delta_acceleration 500.0 # mm/sec² # B axis epsilon_steps_per_mm 100 # may be steps per degree for example epsilon_step_pin xx # Pin for delta stepper step signal epsilon_dir_pin xx # Pin for delta stepper direction epsilon_en_pin xx # Pin for delta enable epsilon_current 1.5 # Z stepper motor current epsilon_max_rate 300.0 # mm/min epsilon_acceleration 500.0 # mm/sec² # C axis zeta_steps_per_mm 100 # may be steps per degree for example zeta_step_pin xx # Pin for delta stepper step signal zeta_dir_pin xx # Pin for delta stepper direction zeta_en_pin xx # Pin for delta enable zeta_current 1.5 # Z stepper motor current zeta_max_rate 300.0 # mm/min zeta_acceleration 500.0 # mm/sec² This configuration is very similar to that of your XYZ axes, and you need to change the values to fit your setup. Optionally if you are using endstops on the A, B or C axis, you need to replace your endstops section with the following ( it is also found in the snippets example ) :

Only for more than 3 axes

NOTE DO NOT use the following syntax if you only have XYZ axis! use the regular endstop config syntax.

Hand in hand

NOTE If you define a homing axis then there MUST be a defined axis with the same designation (eg B endstop MUST have B axis defined) NOTE The ABC axis will always home after the XYZ axis home and will home individually, unless homing_order is defined in which case all axis will home individually in the order specified. ## Endstops new syntax (the name is not significant) # NOTE only a min or a max homing endstop maybe defined endstop.minx.enable true # enable an endstop endstop.minx.pin 1.24 # pin endstop.minx.homing_direction home_to_min # direction it moves to the endstop endstop.minx.homing_position 0 # the cartesian coordinate this is set to when it homes endstop.minx.axis X # the axis designator endstop.minx.max_travel 500 # the maximum travel in mm before it times out endstop.minx.fast_rate 50 # fast homing rate in mm/sec endstop.minx.slow_rate 25 # slow homing rate in mm/sec endstop.minx.retract 5 # bounce off endstop in mm # uncomment for homing to max and comment the minx above #endstop.maxx.enable true # enable an endstop #endstop.maxx.pin 1.25 # pin #endstop.maxx.homing_direction home_to_max # direction it moves to the endstop #endstop.maxx.homing_position 200 # the cartesian coordinate this is set to when it homes #endstop.maxx.axis X # the axis designator #endstop.maxx.max_travel 500 # the maximum travel in mm before it times out #endstop.maxx.fast_rate 50 # fast homing rate in mm/sec #endstop.maxx.slow_rate 25 # slow homing rate in mm/sec #endstop.maxx.retract 5 # bounce off endstop in mm endstop.miny.enable true # enable an endstop endstop.miny.pin 1.26 # pin endstop.miny.homing_direction home_to_min # direction it moves to the endstop endstop.miny.homing_position 0 # the cartesian coordinate this is set to when it homes endstop.miny.axis Y # the axis designator endstop.miny.max_travel 500 # the maximum travel in mm before it times out endstop.miny.fast_rate 50 # fast homing rate in mm/sec endstop.miny.slow_rate 25 # slow homing rate in mm/sec endstop.miny.retract 5 # bounce off endstop in mm # uncomment for homing to max and comment the min above #endstop.maxy.enable true # enable an endstop #endstop.maxy.pin 1.27 # pin #endstop.maxy.homing_direction home_to_max # direction it moves to the endstop #endstop.maxy.homing_position 200 # the cartesian coordinate this is set to when it homes #endstop.maxy.axis Y # the axis designator #endstop.maxy.max_travel 500 # the maximum travel in mm before it times out #endstop.maxy.fast_rate 50 # fast homing rate in mm/sec #endstop.maxy.slow_rate 25 # slow homing rate in mm/sec #endstop.maxy.retract 5 # bounce off endstop in mm endstop.minz.enable true # enable an endstop endstop.minz.pin 1.28 # pin endstop.minz.homing_direction home_to_min # direction it moves to the endstop endstop.minz.homing_position 0 # the cartesian coordinate this is set to when it homes endstop.minz.axis Z # the axis designator endstop.minz.max_travel 100 # the maximum travel in mm before it times out endstop.minz.fast_rate 10 # fast homing rate in mm/sec endstop.minz.slow_rate 2 # slow homing rate in mm/sec endstop.minz.retract 5 # bounce off endstop in mm # uncomment for homing to max and comment the min above #endstop.maxz.enable true # enable an endstop #endstop.maxz.pin 1.29 # pin #endstop.maxz.homing_direction home_to_max # direction it moves to the endstop #endstop.maxz.homing_position 200 # the cartesian coordinate this is set to when it homes #endstop.maxz.axis Z # the axis designator #endstop.maxz.max_travel 100 # the maximum travel in mm before it times out #endstop.maxz.fast_rate 10 # fast homing rate in mm/sec #endstop.maxz.slow_rate 2 # slow homing rate in mm/sec #endstop.maxz.retract 5 # bounce off endstop in mm # optional enable limit switches, actions will stop if any enabled limit switch is triggered #endstop.minx.limit_enable false # set to true to enable the limit on this endstop #endstop.miny.limit_enable false # set to true to enable the limit on this endstop #endstop.minz.limit_enable false # set to true to enable the limit on this endstop # also define the pin needed and the Axis designator if limit on a max pin not defined above #endstop.maxx.enable true # enable an endstop #endstop.maxx.pin 1.25 # pin #endstop.maxx.limit_enable true # set to true to enable the limit on this endstop #endstop.maxx.axis X # the axis designator # OPTIONAL uncomment for homing the A axis to min #endstop.mina.enable true # enable an endstop #endstop.mina.pin 1.29 # pin #endstop.mina.homing_direction home_to_min # direction it moves to the endstop #endstop.mina.homing_position 200 # the cartesian coordinate this is set to when it homes #endstop.mina.axis A # the axis designator #endstop.mina.max_travel 100 # the maximum travel in mm before it times out #endstop.mina.fast_rate 10 # fast homing rate in mm/sec #endstop.mina.slow_rate 2 # slow homing rate in mm/sec #endstop.mina.retract 5 # bounce off endstop in mm # type of machine #corexy_homing false # set to true if homing on a hbot or corexy # optional order in which axis will home, default is they all home at the same time, # if this is set it will force each axis to home one at a time in the specified order #homing_order XYZ # x axis followed by y then z last #move_to_origin_after_home false # move XY to 0,0 after homing #endstop_debounce_count 100 # uncomment if you get noise on your endstops, default is 100 #endstop_debounce_ms 1 # uncomment if you get noise on your endstops, default is 1 millisecond debounce #home_z_first true # uncomment and set to true to home the Z first, otherwise Z homes after XY motors Pyboard 6V DC motors Servo Motor control using MicroPython