Skip to content
This repository has been archived by the owner on Mar 28, 2020. It is now read-only.

piezo_beep #37

Closed
ghost opened this issue Mar 1, 2018 · 43 comments
Closed

piezo_beep #37

ghost opened this issue Mar 1, 2018 · 43 comments

Comments

@ghost
Copy link

ghost commented Mar 1, 2018

Hi, I can use my loudspeaker with the piezo_beep, but I don't know why it doesn't work with very short tones. It works with as short as 50ms, but for shorter ones is not precise at all. What should I do?
Thank you!

@MrYsLab
Copy link
Owner

MrYsLab commented Mar 2, 2018

@franjmt89 The FirmataPlus sketch code is using the standard Arduino tones library. I am not set up to measure the duration, but would you know if you use the Arduino tone library directly, do you get any better precision?

@ghost
Copy link
Author

ghost commented Mar 2, 2018

I'm a very amateur user, so I'm not quite sure how to use the Arduino tone library. When I control the loudspeaker with the Arduino I can get a very precise tone duration.
Right now this is how my code for the loudspeaker looks like:

def PlayTone(frequency, duration):
global speakerPin
board.play_tone(speakerPin, board.TONE_TONE, frequency, duration)

And with this I can get a the frequency I want, but duration smaller than 100ms is not working very well.

@MrYsLab
Copy link
Owner

MrYsLab commented Mar 2, 2018

Most likely, the timing loop within FirmataPlus is causing the issue when you are going below 100ms. The tone feature was added to support tone for s2a_fm users when using Scratch.

May I ask why you need to produce a tone with a duration below 100ms?

@ghost
Copy link
Author

ghost commented Mar 5, 2018

I need to use it as a cue for initiation of task.

@MrYsLab
Copy link
Owner

MrYsLab commented Mar 5, 2018

I just ran the following program with a duration of 10ms and I cannot perceive a difference in the lengths of the beeps. I used both Python 2.17 and 3.6.3 and both work the same. I am running on an Arduino Uno. Could you please try this program and let me know if you are still hearing a problem?

You may have to change the COM port to match your system and the pin for the buzzer.

import time
import sys
import signal

from PyMata.pymata import PyMata


BEEPER = 3  # pin that piezo device is attached to

# create a PyMata instance
board = PyMata("/dev/ttyACM0")


def signal_handler(sig, frm):
    print('You pressed Ctrl+C!!!!')
    if board is not None:
        board.reset()
    sys.exit(0)


signal.signal(signal.SIGINT, signal_handler)

for i in range(10):
    board.play_tone(BEEPER, board.TONE_TONE, 1000, 10)
    time.sleep(1)

board.close()

@MrYsLab
Copy link
Owner

MrYsLab commented Mar 12, 2018

I am closing this issue since I have not heard from you. If you are still having issues, you can leave a comment on this issue and I will receive it. I will reopen the issue if needed.

@MrYsLab MrYsLab closed this as completed Mar 12, 2018
@Kushal4092
Copy link

hi
i tried to run the code above to for the play tone function, it did not work. Then i changed it to this in order for it run

BEEPER = 3 # pin that piezo device is attached to

create a PyMata instance

board = PyMata.Arduino("COM4")
board.play_tone(BEEPER, board.TONE_TONE, 1000, 10)
time.sleep(1)

board.close()

It still did not work. Please let know what i did wrong. I have changed the com
thanks

@MrYsLab
Copy link
Owner

MrYsLab commented Aug 29, 2018

@Kushal4092 I just ran the example program https://github.com/MrYsLab/PyMata/blob/master/examples/piezo/piezo_beep.py and it works here.

Do you have FirmataPlus loaded onto your Arduino? Here are the instructions to do so:
https://github.com/MrYsLab/pymata-aio/wiki/Uploading-FirmataPlus-to-Arduino

Is your piezo device a 5 volt device?

Here is an article on wiring up a piezo device and some sample code to drive it. It does not use Firmata but the tone library directly. Does this work for you?

@Kushal4092
Copy link

This is what i got when trying to setup firmataplus
Arduino: 1.8.2 (Windows 10), Board: "Arduino Leonardo"

C:\Program Files (x86)\Arduino\libraries\Firmata\examples\FirmataPlus32u4\FirmataPlus32u4.ino:44:29: fatal error: FirmataPlus32u4.h: No such file or directory

#include <FirmataPlus32u4.h>

                         ^

compilation terminated.

exit status 1
Error compiling for board Arduino Leonardo.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

@MrYsLab
Copy link
Owner

MrYsLab commented Aug 29, 2018

@Kushal4092 I just downloaded and installed the latest version of the Arduino IDE.
Next, I downloaded libraries.zip from https://github.com/MrYsLab/pymata-aio/blob/master/FirmataPlus/libraries.zip
Then I unzipped this file into C:\Documents/Arduino directory:
image

I then opened the Arduino IDE and selected Examples from the File menu and selected Examples/FirmataPlus32u4 and compiled.

image

Did you install the contents of libraries.zip into the correct directory on your computer?

@Kushal4092
Copy link

now I did installed in the right directory but now its giving me printData("argc = ", argc);
printDATA("x",0)

are these something that i need to worry about.

@MrYsLab
Copy link
Owner

MrYsLab commented Aug 29, 2018

@Kushal4092 Are those coming up as warnings when you compile/upload the sketch? If they are warnings, you can safely ignore them.

@Kushal4092
Copy link

It works thanks. DO you know what is the unit of frequency in the function play_tone. for the duration its in milliseconds.
thanks again

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 5, 2018

I am glad that it works. The frequency is in hz. I will update the API documentation. Thanks.

@Kushal4092
Copy link

for i in range(1):
board.play_tone(BEEPER, board.TONE_TONE, 10, 30000)
time.sleep(1)
why does its last less than 3 sec when i set it to run for 30 sec

@Kushal4092
Copy link

Kushal4092 commented Sep 5, 2018

Also can I use pyfirmata instead of pymata and use playtone function. If so how is it possible?
I found this function "connect_to_firmata("com3")" but not able to make it work. please help. Thanks

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 5, 2018

@Kushal4092 It looks like you might have found a bug in the Arduino tone library. I ran some tests using Arduino sketches, and the duration parameter does not work as expected with the native sketches as well. I will update the code and documentation to remove the duration parameter for the next release.

I suggest you structure your code something like this:

import time
import sys
import signal

from PyMata.pymata import PyMata


BEEPER = 3  # pin that piezo device is attached to

# create a PyMata instance
board = PyMata("/dev/ttyACM0")


def signal_handler(sig, frm):
    print('You pressed Ctrl+C!!!!')
    if board is not None:
        board.reset()
    sys.exit(0)


signal.signal(signal.SIGINT, signal_handler)

# play a continuous tone, wait 30 seconds and then turn tone off
board.play_tone(BEEPER, board.TONE_TONE, 1000, 0)
time.sleep(30)
board.play_tone(BEEPER, board.TONE_NO_TONE, 1000, 0)

board.close()

For pyfirmata, you will need to contact its repository maintainer, since I do not maintain that repository.

@Kushal4092
Copy link

When would the next update? Thanks

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 5, 2018

On second thought, I will not be changing the code, since I do not want to change things for people that may be currently using the duration parameter. I do not wish to break their code. Instead, I will document the preferred way of controlling tone in a note in the wiki. That preferred way is to turn tone on with a continuous tone (duration 0), sleep, and then turn the tone off.

I should have a note completed in the next few days.

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 5, 2018

I just updated the wiki. You can view it here:
https://github.com/MrYsLab/PyMata/wiki/Preferred-Way-To-Control-A-Piezo-Tone-Device

@Kushal4092
Copy link

Hi I have question regrading reading. I was trying to read an analog pin first then write it and read the written value and print. I have been getting 0 after writing it to the pin. Also what kind of value does it out put. for example voltage or different unit.

@Kushal4092
Copy link

This my code
import PyMata
from PyMata.pymata import PyMata
import time

port = 'COM4'
board = PyMata(port)

#A1 = i2c_config(self, pin_type = analog, data_pin = 1)

a1 = board.analog_read(pin=1)

print('a1 read before write: ' + str(a1))

time.sleep(5)

board.analog_write(pin=1,value=5)

a2=board.analog_read(pin=1)

print(a2)

board.close()

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 12, 2018

Hi,
The terminology that Arduino uses can be very confusing. The analog pins A0 and above are only analog inputs (they cannot be configured for analog output). To add to the confusion, the Ax pins can be configured to be digital inputs and outputs, and then the pin number designation changes. For example, A0 is identified as pin 14 if it is used in a digital mode.
Analog output is actually not analog at all, but PWM. For the Uno only pins 3, 5, 6, 9, 10 and 11 can be configured as PWM pins. PWM is an output only mode.
To make things more confusing, on the Uno, pin A4 is used for i2c data, and pin A5 is used for i2c clock.
I hope that this makes things a little clearer, but if not, please feel free to ask any questions you might have.

@Kushal4092
Copy link

Do u have Pymata3 API which i can use as a reference. like then one you had for pymata
http://dawnrobotics.github.io/PyMata/PyMata.pymata.PyMata-class.html

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 12, 2018

There are wiki pages for both PyMata and its API is defined here. and pymata-aio the pymata3 API defined here.

Examples can be found on the wiki page. To get you started here is a blink script using pymata3:

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants

BOARD_LED = 13
board = PyMata3()


def setup():
    board.set_pin_mode(BOARD_LED, Constants.OUTPUT)


def loop():
    print("LED On")
    board.digital_write(BOARD_LED, 1)
    board.sleep(1.0)
    print("LED Off")
    board.digital_write(BOARD_LED, 0)
    board.sleep(1.0)


if __name__ == "__main__":
    setup()
    while True:
        loop()

Notice that pymata3 sleep is used and not the standard library sleep. Also, if you are going to build an application using a blocking library, you may get some unexpected results. If you have any questions, please feel free to ask.

@Kushal4092
Copy link

What does ANALOG mean when using set_pin_mode(a1,ANALOG)does it operate both ways
as input and output

@Kushal4092
Copy link

board.set_pin_mode(0,Constants.ANALOG)
a1 = board.analog_read(pin=0)

print('a1 read before write: ' + str(a1))

#let me know if its right , if not how can i fix it

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 12, 2018

Here is an example of some code that will allow a potentiometer connected to pin A2 to control the brightness of an LED connected to pin 6. We need to set the mode for pin A2 to ANALOG because that triggers firmata (on the Arduino) to automatically report any value changes reported on that pin.

The pin mode for the LED is set to PWM. This is the way the Firmata protocol defines things internally, so pymata3 is consistent with this. When we write to the PWM pin, the command is analog_write. This is to be consistent with the way Arduino describes its PWM write commands.


from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants


"""
Use a potentiometer connected to pin A2 to control
the brightness of an LED connected to pin 6

Pin6 is a PWM pin.
"""

# Led to control via PWM
LED = 6
POT = 2

# create a PyMata3 instance and name it board
board = PyMata3()

# set the pin mode for pin 6 to be PWM
board.set_pin_mode(LED, Constants.PWM)

# set the pin mode for pin a2 to be analog in.
# we set the pin mode so that firmata will automatically
# report any value changes for a2
board.set_pin_mode(POT, Constants.ANALOG)

# The pot will return a value between 0 and 1024.
# PWM outputs take a value of 0-256 so we will scale the value of the
# pot to match.

while True:
    try:
        pot_value = board.analog_read(POT)
        led_brightness = pot_value // 4

        board.analog_write(LED, led_brightness)
    except KeyboardInterrupt:
        board.shutdown()



@MrYsLab
Copy link
Owner

MrYsLab commented Sep 12, 2018

Here is an adaptation of your example:

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants

board = PyMata3()

ANALOG_PIN = 2  # this is A2

board.set_pin_mode(ANALOG_PIN, Constants.ANALOG)
# forever read the analog pin until control C is entered
while True:
    try:
        analog_value = board.analog_read(ANALOG_PIN)
        print('Analog read', analog_value)
    except KeyboardInterrupt:
        board.shutdown()

@Kushal4092
Copy link

why does the the out put from pin 6 lower than the input? is it due to fact that it has different transistors on the arduino.

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 14, 2018

What mode are you setting - digital or PWM? When you say a lower level, what levels are you seeing?

@Kushal4092
Copy link

Kushal4092 commented Sep 14, 2018

PWM which analog_write. the input to A2 is 0.8v and the output from pin 6 is 0.73v. I think the loss of voltage is caused due to the calculation. Also why does the program closes? I load the program and look at my reading and then stop it the program, then re-run the program and it stops, I got the run it again. What am i doing wrong?

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 14, 2018

Can you copy the code here? I cannot tell why it may be stopping without looking at it.

@Kushal4092
Copy link

Kushal4092 commented Sep 14, 2018

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants
# Led to control via PWM
LED = 6
POT = 2

# create a PyMata3 instance and name it board
board = PyMata3()

# set the pin mode for pin 6 to be PWM
board.set_pin_mode(LED, Constants.PWM)

# set the pin mode for pin a2 to be analog in.
# we set the pin mode so that firmata will automatically

# report any value changes for a2
board.set_pin_mode(POT, Constants.ANALOG)

# The pot will return a value between 0 and 1024.
# PWM outputs take a value of 0-256 so we will scale the value of the
# pot to match.

while True:
try:
pot_value = board.analog_read(POT)
print(pot_value)
led_brightness = pot_value // 4

   board.analog_write(LED, led_brightness)
    print(led_brightness)`
except KeyboardInterrupt:
    board.shutdown()

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 14, 2018

Ok, that looks like my code. By the way, to copy a program here is to surround it with ``` before the first line of code and after the last line and the code will be formatted properly.
like this:

some code

I don't think I understand. Are you saying that if you start the program, hit control C and restart it, the code stops by itself? Does it print out any exceptions?

@Kushal4092
Copy link

yes I am just playing with the code. If I press ctrl+c its does not stop, i think i need to make the function keyboardInterrupt. but i stop it using IDE(pycharm) and rerun it gives me this
pymata_aio Version 2.16 Copyright (c) 2015-2016 Alan Yorinks All rights reserved.

Using COM Port:com4

Initializing Arduino - Please wait... list index out of range
Shutting down ...

Process finished with exit code 0

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 14, 2018

PyCharm does not pass on the Control C to the running program.
To stop a program running in PyCharm, press the red square on the left side of the dialog box. This generates a Control C that is sent to the program.:
image
To restart it, press the green triangle:
image

@Kushal4092
Copy link

The input voltage at A2 is 0.806v and the out to D6 is 0.79v do u whats is causing this error. I am using my DMM to to just see the change in voltage from input to output.

@MrYsLab
Copy link
Owner

MrYsLab commented Sep 14, 2018

It is probably due to 2 factors. The first is the accuracy of the Arduino ADC (analog input). There is a discussion of this in this article. If you scroll to the bottom of the page, the article quantifies this in terms of voltage.

The second is the fact that PWM is not a true analog ouput but a simulated one. This article might help to understand this.

@Kushal4092
Copy link

Hi,
I am trying to read the digital pin but it always give me 0 when I write 1.
`from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants
import time

board = PyMata3()
pin10 = 10
board.set_pin_mode(pin10, Constants.OUTPUT)
timeout = time.time() + 5
board.digital_pin_write(pin10, value=1)
while True:
a = board.digital_read(pin10)
b=board.analog_read(pin10)
print("b = ", b)
print(a)
if time.time() > timeout:
break
`

@MrYsLab
Copy link
Owner

MrYsLab commented Oct 16, 2018

The Firmata protocol works differently than a straight Arduino sketch. There is some documentation here: https://github.com/firmata/protocol/blob/master/protocol.md#pin-state-query.

Essentially, with Firmata, when you set a pin as an output pin, if you write to it and then read it back, it will not accurately reflect the level that you wrote. The pin can be set up to be either an input pin or output pin but cannot be both. The mode is selected by the set_pin_mode call.

Also, you cannot do an analog_read on a digital pin, and pin 10 is a digital pin.

Let me know if that does not answer your question.

@Kushal4092
Copy link

Kushal4092 commented Nov 12, 2018

Hi, I am using Pymata3
https://htmlpreview.github.io/?https://github.com/MrYsLab/pymata-aio/blob/master/documentation/html/pymata3.m.html#header-classes

library and I am trying to read Rx from my arduino but it says I need to upload FirmataPlusRB. when I do that I get an error. When I upload FirmataPlusRBPixy its fine, but when I am trying to use the pixy_get_block I get empty [] and when I wait but a bit longer the program crashes and says
Initializing Arduino - Please wait... Write exception
Write exception
Write exception

Shutting down ...
Write exception

I was using StandardFirmata and It was working fine but I was not able to use the this function.

this is the Code:
board.pixy_init(max_blocks=1, cb=None,cb_type=Constants.CB_TYPE_ASYNCIO) print(board.pixy_get_blocks())

@MrYsLab
Copy link
Owner

MrYsLab commented Nov 12, 2018

I have moved this issue over to the pymata-aio distribution and you may find it here:
MrYsLab/pymata-aio#88

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants