machine.Signal.rst 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. .. currentmodule:: machine
  2. .. _machine.Signal:
  3. class Signal -- control and sense external I/O devices
  4. ======================================================
  5. The Signal class is a simple extension of the `Pin` class. Unlike Pin, which
  6. can be only in "absolute" 0 and 1 states, a Signal can be in "asserted"
  7. (on) or "deasserted" (off) states, while being inverted (active-low) or
  8. not. In other words, it adds logical inversion support to Pin functionality.
  9. While this may seem a simple addition, it is exactly what is needed to
  10. support wide array of simple digital devices in a way portable across
  11. different boards, which is one of the major MicroPython goals. Regardless
  12. of whether different users have an active-high or active-low LED, a normally
  13. open or normally closed relay - you can develop a single, nicely looking
  14. application which works with each of them, and capture hardware
  15. configuration differences in few lines in the config file of your app.
  16. Example::
  17. from machine import Pin, Signal
  18. # Suppose you have an active-high LED on pin 0
  19. led1_pin = Pin(0, Pin.OUT)
  20. # ... and active-low LED on pin 1
  21. led2_pin = Pin(1, Pin.OUT)
  22. # Now to light up both of them using Pin class, you'll need to set
  23. # them to different values
  24. led1_pin.value(1)
  25. led2_pin.value(0)
  26. # Signal class allows to abstract away active-high/active-low
  27. # difference
  28. led1 = Signal(led1_pin, invert=False)
  29. led2 = Signal(led2_pin, invert=True)
  30. # Now lighting up them looks the same
  31. led1.value(1)
  32. led2.value(1)
  33. # Even better:
  34. led1.on()
  35. led2.on()
  36. Following is the guide when Signal vs Pin should be used:
  37. * Use Signal: If you want to control a simple on/off (including software
  38. PWM!) devices like LEDs, multi-segment indicators, relays, buzzers, or
  39. read simple binary sensors, like normally open or normally closed buttons,
  40. pulled high or low, Reed switches, moisture/flame detectors, etc. etc.
  41. Summing up, if you have a real physical device/sensor requiring GPIO
  42. access, you likely should use a Signal.
  43. * Use Pin: If you implement a higher-level protocol or bus to communicate
  44. with more complex devices.
  45. The split between Pin and Signal come from the usecases above and the
  46. architecture of MicroPython: Pin offers the lowest overhead, which may
  47. be important when bit-banging protocols. But Signal adds additional
  48. flexibility on top of Pin, at the cost of minor overhead (much smaller
  49. than if you implemented active-high vs active-low device differences in
  50. Python manually!). Also, Pin is a low-level object which needs to be
  51. implemented for each support board, while Signal is a high-level object
  52. which comes for free once Pin is implemented.
  53. If in doubt, give the Signal a try! Once again, it is offered to save
  54. developers from the need to handle unexciting differences like active-low
  55. vs active-high signals, and allow other users to share and enjoy your
  56. application, instead of being frustrated by the fact that it doesn't
  57. work for them simply because their LEDs or relays are wired in a slightly
  58. different way.
  59. Constructors
  60. ------------
  61. .. class:: Signal(pin_obj, invert=False)
  62. Signal(pin_arguments..., \*, invert=False)
  63. Create a Signal object. There're two ways to create it:
  64. * By wrapping existing Pin object - universal method which works for
  65. any board.
  66. * By passing required Pin parameters directly to Signal constructor,
  67. skipping the need to create intermediate Pin object. Available on
  68. many, but not all boards.
  69. The arguments are:
  70. - ``pin_obj`` is existing Pin object.
  71. - ``pin_arguments`` are the same arguments as can be passed to Pin constructor.
  72. - ``invert`` - if True, the signal will be inverted (active low).
  73. Methods
  74. -------
  75. .. method:: Signal.value([x])
  76. This method allows to set and get the value of the signal, depending on whether
  77. the argument ``x`` is supplied or not.
  78. If the argument is omitted then this method gets the signal level, 1 meaning
  79. signal is asserted (active) and 0 - signal inactive.
  80. If the argument is supplied then this method sets the signal level. The
  81. argument ``x`` can be anything that converts to a boolean. If it converts
  82. to ``True``, the signal is active, otherwise it is inactive.
  83. Correspondence between signal being active and actual logic level on the
  84. underlying pin depends on whether signal is inverted (active-low) or not.
  85. For non-inverted signal, active status corresponds to logical 1, inactive -
  86. to logical 0. For inverted/active-low signal, active status corresponds
  87. to logical 0, while inactive - to logical 1.
  88. .. method:: Signal.on()
  89. Activate signal.
  90. .. method:: Signal.off()
  91. Deactivate signal.