I would rather run the ultrasonics asynchronously. Also since the kids may not be be that advanced in our curriculum I prefer to stay away from threads. The last code that I posted works fine.
On Tuesday, April 12, 2016 at 10:37:52 AM UTC-7, Ytai wrote: > > Use PWM output to generate periodic, precisely timed trigger pulses. > On Apr 12, 2016 10:36, "Vic Wintriss" <[email protected] <javascript:>> > wrote: > >> I thought I was following your instructions. I am using the 4-pin sensor >> as suggested and code that I thought was standard. What did you tell me to >> do that I am not doing? >> >> On Monday, April 11, 2016 at 1:28:48 PM UTC-7, Ytai wrote: >>> >>> I feel like I gave you my best advice, but you seem to insist on doing >>> it in a way that's not supposed to work. >>> On Apr 11, 2016 1:03 PM, "Vic Wintriss" <[email protected]> wrote: >>> >>>> When I use this code: >>>> >>>> ioio.beginBatch(); >>>> rightStrobe.write(true); >>>> rightStrobe.write(false); >>>> ioio.endBatch(); >>>> >>>> I get this beautiful result: >>>> >>>> >>>> <https://lh3.googleusercontent.com/-qyhO2zqtmoY/VwwBnL2vE7I/AAAAAAAAAAg/xyOLBnQBnuIvFhdp0IdprRb_qVvx6Hckw/s1600/bad.PNG> >>>> >>>> But the code hangs up and I get no duration readings. >>>> >>>> If I use this code: >>>> >>>> rightStrobe.write(true); >>>> SystemClock.sleep(10); >>>> rightStrobe.write(false); >>>> >>>> rightDistance = (int) (rightInput.getDuration() * CONVERSION_FACTOR); >>>> I get this awful situation, but it works. Anything less than a 10 >>>> millisec sleep fails. >>>> >>>> >>>> <https://lh3.googleusercontent.com/-WEm_XYa5PF8/VwwBBYuVQ9I/AAAAAAAAAAY/15jv4SAWC3ouxIcAW9EyO7GC-SEZgtSZA/s1600/works.png> >>>> >>>> On Monday, April 4, 2016 at 9:25:36 PM UTC-7, Ytai wrote: >>>>> >>>>> Sorry, I meant "output" from the IOIO's point of view. >>>>> Let me make sure I understand you correctly: are you claiming that >>>>> you're emitting a shorter-than-10-ms trigger pulse, the pulse gets >>>>> emitted >>>>> correctly as verified by a scope, the echo pulse gets emitted correctly >>>>> as >>>>> verified by a scope, but your app is blocked on waitPulseGetDuration()? >>>>> If >>>>> that's the case, the only thing I can imagine is that the wait*() method >>>>> is >>>>> called after the pulse has already comes back. >>>>> >>>>> Have you considered using PwmOutput as trigger, as per my suggestion? >>>>> Then you can use getDuration() and never have to block. I think this is a >>>>> rather elegant solution. >>>>> >>>>> On Mon, Apr 4, 2016 at 10:51 AM, <[email protected]> wrote: >>>>> >>>>>> The output pulse (echo pulse returning from the ultrasonic sensor) is >>>>>> correct...it is milli secs long and varies proportionately with the >>>>>> distance. I am not using Bluetooth...the Android is directly connected >>>>>> to >>>>>> the ioio board. It is the trigger pulse that must be long...more than >>>>>> 10 >>>>>> millisec...for the program to run. It hangs up with smaller trigger >>>>>> pulses. I can easily generate 10 microsec trigger pulses...as observed >>>>>> on >>>>>> scope...but then the program hangs up. Ideas? >>>>>> >>>>>> On Friday, April 1, 2016 at 9:55:17 PM UTC-7, Ytai wrote: >>>>>>> >>>>>>> When you look at the waveforms, what do you see as the output pulse? >>>>>>> My guess would be that it is very narrow, in the order of a couple of >>>>>>> usec >>>>>>> perhaps, and if that's indeed the case, it is likely because both >>>>>>> messages >>>>>>> comprising the pulse got collapsed into the same packet over one of the >>>>>>> slower connections such as Bluetooth. In short, trying to achieve >>>>>>> precise >>>>>>> timing of any sort at this time scale is a bad idea. It would be >>>>>>> possible >>>>>>> to add a one-shot feature to the IOIO to achieve that. If you want this >>>>>>> reading periodically, consider using a PwmOutput to keep triggering the >>>>>>> sensor without your intervention at very precise pulse widths and >>>>>>> period. >>>>>>> Another option would be to use a version of those sensors that emits an >>>>>>> analog voltage corresponding to the distance. >>>>>>> On Apr 1, 2016 9:38 PM, <[email protected]> wrote: >>>>>>> >>>>>>>> It's a new iARoC (International Autonomous Robot Competition) year >>>>>>>> (2016) and we are back to the ultrasonic sensor problem. This year I >>>>>>>> am >>>>>>>> using the 4-pin version. The following code works: >>>>>>>> >>>>>>>> public void readRight() throws ConnectionLostException, >>>>>>>> InterruptedException >>>>>>>> {//This code works with the 4-pin sensor...don't change anything! >>>>>>>> rightStrobe.write(true); >>>>>>>> SystemClock.*sleep*(10); >>>>>>>> rightStrobe.write(false); >>>>>>>> rightDistance = (int) (rightInput.getDuration() * >>>>>>>> *CONVERSION_FACTOR*); >>>>>>>> } >>>>>>>> >>>>>>>> But it will not work with less than a 10 ms long trigger pulse. I >>>>>>>> don't understand this, because the ultrasonic sensor spec says that >>>>>>>> the >>>>>>>> trigger pulse should be around 10 micro sec. Do you have any idea why >>>>>>>> I >>>>>>>> need such a long trigger pulse. I verified the waveforms with a >>>>>>>> scope. It >>>>>>>> seems to be the case with both the 4-pin and the 3-pin version. >>>>>>>> >>>>>>>> On Thursday, April 23, 2015 at 9:43:50 PM UTC-7, Ytai wrote: >>>>>>>>> >>>>>>>>> You can add a TimerTask to interrupt the thread after some >>>>>>>>> timeout. Search the forum for examples if you need them. If you don't >>>>>>>>> want >>>>>>>>> to delay all the other 5 if one is stuck you can easily run 6 sensors >>>>>>>>> on 6 >>>>>>>>> different threads. >>>>>>>>> >>>>>>>>> On Wed, Apr 22, 2015 at 2:42 PM, Daniel Brown <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> if one PulseInput pin is open or has not received a pulse and you >>>>>>>>>> call getDuration() it will block you from reading all other >>>>>>>>>> PulseInput pins >>>>>>>>>> until it has received at least one pulse. We have found that one bad >>>>>>>>>> sensor >>>>>>>>>> will stop you from reading any other sensor. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Friday, April 10, 2015 at 6:59:52 PM UTC-6, Daniel Brown wrote: >>>>>>>>>>> >>>>>>>>>>> We have a project that uses 6 distance finders, when we try to >>>>>>>>>>> call .getDuration() on more then one all further reading freezes. >>>>>>>>>>> >>>>>>>>>>> protected void setup() throws ConnectionLostException { >>>>>>>>>>> >>>>>>>>>>> // front left pulse and echo >>>>>>>>>>> echoPinfl_ = ioio_.openPulseInput(6, PulseMode.POSITIVE); >>>>>>>>>>> triggerPinfl_ = ioio_.openDigitalOutput(7); >>>>>>>>>>> // front middle pulse and echo >>>>>>>>>>> echoPinfm_ = ioio_.openPulseInput(2, PulseMode.POSITIVE); >>>>>>>>>>> triggerPinfm_ = ioio_.openDigitalOutput(4); >>>>>>>>>>> >>>>>>>>>>> ... >>>>>>>>>>> >>>>>>>>>>> public void loop() throws ConnectionLostException, >>>>>>>>>>> InterruptedException { >>>>>>>>>>> // updates front left sensor >>>>>>>>>>> try{ >>>>>>>>>>> triggerPinfl_.write(false); >>>>>>>>>>> Thread.sleep(5); >>>>>>>>>>> triggerPinfl_.write(true); >>>>>>>>>>> Thread.sleep(1); >>>>>>>>>>> triggerPinfl_.write(false); >>>>>>>>>>> echosecondsfl_ = (int)(echoPinfl_.getDuration() * 1000 * 1000); >>>>>>>>>>> echoDistanceCmfl_ = echosecondsfl_ / 29 / 2; >>>>>>>>>>> }catch (ConnectionLostException e) { throw e;} >>>>>>>>>>> // updates front middle sensor >>>>>>>>>>> try{ >>>>>>>>>>> triggerPinfm_.write(false); >>>>>>>>>>> Thread.sleep(5); >>>>>>>>>>> triggerPinfm_.write(true); >>>>>>>>>>> Thread.sleep(1); >>>>>>>>>>> triggerPinfm_.write(false); >>>>>>>>>>> // echosecondsfm_ = (int)(echoPinfm_.getDuration() * 1000 * >>>>>>>>>>> 1000); //if this line is commented in all further input stops >>>>>>>>>>> // echoDistanceCmfm_ = echosecondsfm_ / 29 / 2; >>>>>>>>>>> }catch (ConnectionLostException e) { throw e;} >>>>>>>>>>> >>>>>>>>>>> ... >>>>>>>>>>> >>>>>>>>>>> On Friday, May 16, 2014 at 11:03:20 AM UTC-6, Ytai wrote: >>>>>>>>>>>> >>>>>>>>>>>> Thanks for sharing! >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Thu, May 15, 2014 at 9:25 PM, <[email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Here is some code that works great with the Parallax Ping))) >>>>>>>>>>>>> with the circuit in the file attached (thanks to Ytai): >>>>>>>>>>>>> >>>>>>>>>>>>> private int read(DigitalOutput strobe, PulseInput input, int >>>>>>>>>>>>> inputPin) throws ConnectionLostException, InterruptedException // >>>>>>>>>>>>> Order of following statements is very important...do not change >>>>>>>>>>>>> >>>>>>>>>>>>> { >>>>>>>>>>>>> int distance = 0; >>>>>>>>>>>>> >>>>>>>>>>>>> ioio.beginBatch(); >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> strobe.write(true); >>>>>>>>>>>>> >>>>>>>>>>>>> input = ioio.openPulseInput(inputPin, >>>>>>>>>>>>> PulseMode.POSITIVE); >>>>>>>>>>>>> >>>>>>>>>>>>> ioio.endBatch(); >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> SystemClock.sleep(40); >>>>>>>>>>>>> >>>>>>>>>>>>> strobe.write(false); >>>>>>>>>>>>> >>>>>>>>>>>>> distance += (int) (input.getDuration() * >>>>>>>>>>>>> CONVERSION_FACTOR); >>>>>>>>>>>>> >>>>>>>>>>>>> input.close(); >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> return distance; >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Wednesday, April 30, 2014 10:25:27 AM UTC-7, >>>>>>>>>>>>> [email protected] wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> I'll clean up the class and post it. Hope other people can >>>>>>>>>>>>>> use it. Works very solidly with the Parallax Ping))) ultrasonic >>>>>>>>>>>>>> module. >>>>>>>>>>>>>> Great suggestion to use only one pin for both input and >>>>>>>>>>>>>> output. It would even have saved me a part on the pc boards. >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Sunday, April 27, 2014 8:24:19 PM UTC-7, Ytai wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Cool. If you can create a nice class for using the PING >>>>>>>>>>>>>>> (where the ctor gets a IOIO and two pin numbers, and there's a >>>>>>>>>>>>>>> getDistance() method) and share it on this forum, it would be a >>>>>>>>>>>>>>> decent >>>>>>>>>>>>>>> return for our efforts :) As a side note, since you're doing >>>>>>>>>>>>>>> the open-close >>>>>>>>>>>>>>> trick, you might as well use a single pin and open-close the >>>>>>>>>>>>>>> digital output >>>>>>>>>>>>>>> as well and not need the driver chip, so you can even further >>>>>>>>>>>>>>> simplify both >>>>>>>>>>>>>>> your code and your circuit. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Sun, Apr 27, 2014 at 8:19 PM, Vic Wintriss < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I finally got it to work using your last suggestion. This >>>>>>>>>>>>>>>> code works that you recommended works perfectly. Thanks so >>>>>>>>>>>>>>>> much for >>>>>>>>>>>>>>>> sticking with us. We've got 30 or 40 kids using this code at >>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>> International Autonomous Robot Competition (iARoC 2014) coming >>>>>>>>>>>>>>>> up at the >>>>>>>>>>>>>>>> end of June. Check out iaroc.org. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> triggerHigh(); >>>>>>>>>>>>>>>> in = openPulseInput(); >>>>>>>>>>>>>>>> sleep(20ms); // wait until the pulse input module is ready >>>>>>>>>>>>>>>> for a pulse. >>>>>>>>>>>>>>>> triggerLow(); // kick off a measurement (falling edge does >>>>>>>>>>>>>>>> not trigger the pulse input) >>>>>>>>>>>>>>>> duration = in.getDuration(); >>>>>>>>>>>>>>>> in.close(); >>>>>>>>>>>>>>>> return duration; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Sunday, April 27, 2014 11:36:53 AM UTC-7, Ytai wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Let me shed some light on the internals of PulseInput: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - A timer is running on the IOIO set to 200Hz (5ms). >>>>>>>>>>>>>>>>> - As soon as the pulse input module is opened, and >>>>>>>>>>>>>>>>> every time after a pulse is captured the module will be >>>>>>>>>>>>>>>>> put in the "ready" >>>>>>>>>>>>>>>>> state. >>>>>>>>>>>>>>>>> - Every time the 200Hz timer triggers, each "ready" >>>>>>>>>>>>>>>>> module will be activated, i.e. put in a state where it is >>>>>>>>>>>>>>>>> waiting for a new >>>>>>>>>>>>>>>>> pulse. >>>>>>>>>>>>>>>>> - Once activated, the module will wait forever (or >>>>>>>>>>>>>>>>> until closed) for a pulse, then measure its duration, then >>>>>>>>>>>>>>>>> sends the result >>>>>>>>>>>>>>>>> to the Android. >>>>>>>>>>>>>>>>> - So this means that effectively no matter what the >>>>>>>>>>>>>>>>> actual pulse rate is, you will never get more than 200 >>>>>>>>>>>>>>>>> reports per second. >>>>>>>>>>>>>>>>> This has been done on purpose to prevent a high frequency >>>>>>>>>>>>>>>>> pulse train from >>>>>>>>>>>>>>>>> saturating the connection between the IOIO and the >>>>>>>>>>>>>>>>> Android. This also means >>>>>>>>>>>>>>>>> that there is a potential "dead time" of up to 5ms after >>>>>>>>>>>>>>>>> opening or between >>>>>>>>>>>>>>>>> pulses, during which a pulse would not be detected. >>>>>>>>>>>>>>>>> - On the Android side, every pulse report finds its >>>>>>>>>>>>>>>>> way to your PulseInput object. You can then read it in one >>>>>>>>>>>>>>>>> of three ways: >>>>>>>>>>>>>>>>> - getDuration() will return the last report. It >>>>>>>>>>>>>>>>> will generally not block, then only exception is until >>>>>>>>>>>>>>>>> the first report >>>>>>>>>>>>>>>>> arrives. >>>>>>>>>>>>>>>>> - getDurationSync() will always block until a new >>>>>>>>>>>>>>>>> report comes in, then return it. So you can be sure >>>>>>>>>>>>>>>>> that the report is new. >>>>>>>>>>>>>>>>> - getDurationBuffered() pulls pulses one by one >>>>>>>>>>>>>>>>> from a queue. When the queue becomes empty it behave >>>>>>>>>>>>>>>>> like >>>>>>>>>>>>>>>>> getDurationSync(), i.e. waits until a new report comes >>>>>>>>>>>>>>>>> in. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> The Arduino approach cannot be directly applied to the >>>>>>>>>>>>>>>>> IOIO API, since you have to take into account that because of >>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> communication between the Android and the IOIO, much of the >>>>>>>>>>>>>>>>> IOIO API has >>>>>>>>>>>>>>>>> been designed to be asynchronous in nature. If you were to >>>>>>>>>>>>>>>>> bake the PING >>>>>>>>>>>>>>>>> driver directly into the IOIO firmware, you can use a similar >>>>>>>>>>>>>>>>> approach to >>>>>>>>>>>>>>>>> Arduino's (although you'd probably want to implement it in a >>>>>>>>>>>>>>>>> non-blocking >>>>>>>>>>>>>>>>> way, since the IOIO allows everything to be used >>>>>>>>>>>>>>>>> concurrently). The reason >>>>>>>>>>>>>>>>> why I have not done that is because I tried to focus on >>>>>>>>>>>>>>>>> generic use-cases >>>>>>>>>>>>>>>>> rather than on one peculiar sensor interface. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Sun, Apr 27, 2014 at 10:57 AM, Duane DeSieno < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> My confusion is maybe over the way getDuration works. >>>>>>>>>>>>>>>>>> Does it delay 5ms before looking for the pulse or does it >>>>>>>>>>>>>>>>>> look immediately? >>>>>>>>>>>>>>>>>> I put 555 timer on the input pin and set it up for 3.15hz >>>>>>>>>>>>>>>>>> and 25.4% duty cycle or an 80.6ms pulse every 317.4ms. >>>>>>>>>>>>>>>>>> I called getDuration roughly every 100ms. It did not >>>>>>>>>>>>>>>>>> block and returned the same value several times before the >>>>>>>>>>>>>>>>>> next pulse >>>>>>>>>>>>>>>>>> occurred(not what I expected). >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Looked at the Arduino approach to using the PING and they >>>>>>>>>>>>>>>>>> use just one pin, changing from output after sending a pulse >>>>>>>>>>>>>>>>>> to ping to an >>>>>>>>>>>>>>>>>> input for their get duration call. >>>>>>>>>>>>>>>>>> Since they don't impose a 5ms delay, they get the >>>>>>>>>>>>>>>>>> duration of the return pulse. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Thanks for you help on this. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Duane >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> You received this message because you are subscribed to >>>>>>>>>>>>>>>>>> the Google Groups "ioio-users" group. >>>>>>>>>>>>>>>>>> To unsubscribe from this group and stop receiving emails >>>>>>>>>>>>>>>>>> from it, send an email to [email protected] >>>>>>>>>>>>>>>>>> . >>>>>>>>>>>>>>>>>> To post to this group, send email to >>>>>>>>>>>>>>>>>> [email protected]. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Visit this group at http://groups.google.com/group >>>>>>>>>>>>>>>>>> /ioio-users. >>>>>>>>>>>>>>>>>> For more options, visit https://groups.google.com/d/op >>>>>>>>>>>>>>>>>> tout. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>>>>>>>> Google Groups "ioio-users" group. >>>>>>>>>>>>>>>> To unsubscribe from this group and stop receiving emails >>>>>>>>>>>>>>>> from it, send an email to [email protected]. >>>>>>>>>>>>>>>> To post to this group, send email to >>>>>>>>>>>>>>>> [email protected]. >>>>>>>>>>>>>>>> Visit this group at http://groups.google.com/ >>>>>>>>>>>>>>>> group/ioio-users. >>>>>>>>>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>>>>> Google Groups "ioio-users" group. >>>>>>>>>>>>> To unsubscribe from this group and stop receiving emails from >>>>>>>>>>>>> it, send an email to [email protected]. >>>>>>>>>>>>> To post to this group, send email to [email protected] >>>>>>>>>>>>> . >>>>>>>>>>>>> Visit this group at http://groups.google.com/group/ioio-users. >>>>>>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>> Google Groups "ioio-users" group. >>>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>>> send an email to [email protected]. >>>>>>>>>> To post to this group, send email to [email protected]. >>>>>>>>>> Visit this group at http://groups.google.com/group/ioio-users. >>>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups "ioio-users" group. >>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>> send an email to [email protected]. >>>>>>>> To post to this group, send email to [email protected]. >>>>>>>> Visit this group at https://groups.google.com/group/ioio-users. >>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>> >>>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "ioio-users" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an email to [email protected]. >>>>>> To post to this group, send email to [email protected]. >>>>>> Visit this group at https://groups.google.com/group/ioio-users. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> >>>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "ioio-users" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> To post to this group, send email to [email protected]. >>>> Visit this group at https://groups.google.com/group/ioio-users. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "ioio-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> To post to this group, send email to [email protected] >> <javascript:>. >> Visit this group at https://groups.google.com/group/ioio-users. >> For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "ioio-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/ioio-users. For more options, visit https://groups.google.com/d/optout.
