Author Topic: Maxbotix Ultrasonic Sensor and Digispark  (Read 11142 times)

septentriones

  • Newbie
  • *
  • Posts: 8
Maxbotix Ultrasonic Sensor and Digispark
« on: November 08, 2013, 10:07:25 pm »
Hello! I'm new to Arduino in general and especially to Digispark and I am having some difficulty making code that functioned on my Arduino Uno work on my Digispark. I have an ultrasonic sensor from Maxbotix (MB1242) and I have successfully used the sample code they provide in their documentation (see here: http://www.maxbotix.com/documents/I2CXL-MaxSonar-EZ_Datasheet.pdf) on my Uno but I cannot seem to modify it in order to function on the Digispark.

I have replaced the Wire calls with the (I believe) equivalent TinyWireM calls and I still read a constant range. (On the Uno the range is read from 20-765 in cm while on the Digispark I always obtain a constant value of 20736.)

My physical wiring connects the sensor's Vcc to 5V and ground to ground while SCL (5) connects to P2 and SDA (4) connects to P0 and I'm relatively sure that is not a mistake (though enlighten me if it is).

I'm assuming I've made some foolish coding oversight and I would appreciate it if someone could explain what I have done wrong and how I should go about fixing it.

Thanks

Code: [Select]
/* Code for Arduino Uno R3 modified for Digispark
Assumes the sensor is using the default address
Sensor Connections:
Pin 7 to GND
Pin 6 to 5V
Pin 5 to SCL
Pin 4 to SDA
Requires pull-ups for SCL and SDA connected to 5V to work reliably
*/

#include "DigiKeyboard.h"                //included in order to debug
#include "TinyWireM.h"
//The Arduino Wire library uses the 7-bit version of the address, so the code example uses 0x70 instead of the 8-bit 0xE0
//I don't know if this statement holds true for TinyWireM

#define SensorAddress byte(0x70)
//The sensors ranging command has a value of 0x51
#define RangeCommand byte(0x51)
//These are the two commands that need to be sent in sequence to change the sensor address
#define ChangeAddressCommand1 byte(0xAA)
#define ChangeAddressCommand2 byte(0xA5)
 
void setup() {
 Serial.begin(9600); //Open serial connection at 9600 baud
 TinyWireM.begin(); //Initiate TinyWireM library for I2C communications with the I2CXL-MaxSonar-EZ
}
 
void loop(){
 takeRangeReading(); //Tell the sensor to perform a ranging cycle
 delay(100); //Wait for sensor to finish
 word range = requestRange(); //Get the range from the sensor
 DigiKeyboard.println("Range: ");
 DigiKeyboard.println(range); //Print to the user
}
//Commands the sensor to take a range reading
void takeRangeReading(){
 TinyWireM.beginTransmission(SensorAddress); //Start addressing
 TinyWireM.send(RangeCommand); //send range command
 TinyWireM.endTransmission(); //Stop and do something else now
}
//Returns the last range that the sensor determined in its last ranging cycle in centimeters. Returns 0 if there is no communication.
word requestRange(){
 TinyWireM.requestFrom(SensorAddress, byte(2));
 if(TinyWireM.available() >= 2){ //Sensor responded with the two bytes
 byte HighByte = TinyWireM.receive(); //Read the high byte back
 byte LowByte = TinyWireM.receive(); //Read the low byte back
 word range = word(HighByte, LowByte); //Make a 16-bit word out of the two bytes for the range
 return range;
 }
 else {
 return word(0); //Else nothing was received, return 0
 }
}
/* Commands a sensor at oldAddress to change its address to newAddress
oldAddress must be the 7-bit form of the address that is used by Wire
7BitHuh determines whether newAddress is given as the new 7 bit version or the 8 bit version of the address
If true, if is the 7 bit version, if false, it is the 8 bit version
*/
void changeAddress(byte oldAddress, byte newAddress, boolean SevenBitHuh){
 TinyWireM.beginTransmission(oldAddress); //Begin addressing
 TinyWireM.send(ChangeAddressCommand1); //Send first change address command
 TinyWireM.send(ChangeAddressCommand2); //Send second change address command
 
 byte temp;
 if(SevenBitHuh){ temp = newAddress << 1; } //The new address must be written to the sensor
 else { temp = newAddress; } //in the 8bit form, so this handles automatic shifting
 
 TinyWireM.send(temp); //Send the new address to change to
 
 TinyWireM.endTransmission();
}

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #1 on: November 09, 2013, 01:32:36 am »
You need pull-ups between the pins and 5v - these are internal on the Atmega (Uno MCU) but not Attiny (Digispark MCU)

So put a 4.7k (or similar) resistor between 5v and P0 , and another between 5v and P2 - leave the rest connected as you have it.

septentriones

  • Newbie
  • *
  • Posts: 8
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #2 on: November 09, 2013, 04:45:08 pm »
It makes sense that pull-ups are required (and I wouldn't have figured out that that was the issue) but when I attached a 4.7K resistor from 5v to P0 and another from 5v to P2 (while still keeping SCL and SDA connected to those respective pins) I no longer receive any output from my print statements (using DigiKeyboard). Perhaps I need to have a different resistance value or somehow this interferes with the ability for the digispark to output information back to my computer. I'm going to keep searching for this on my own but any additional input would be appreciated.

EDIT: I have not disconnected the onboard LED from pin 2, is that still a problem for I2C (I know it was an issue with the Model B when the LED was connected to P0)? The digispark I am currently using is brand new and indicates that it is a rev4. Additionally, when I connect the digispark to my computer (to power it) it makes the windows connect/disconnect sound for usb devices (not sure what else to call that sound).
« Last Edit: November 09, 2013, 05:10:10 pm by septentriones »

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #3 on: November 09, 2013, 06:58:21 pm »
Try changing all delay()s to DigiKeyboard.delay() - you have to use that kind of delay with the Digikeyboard to keep the USB alive

septentriones

  • Newbie
  • *
  • Posts: 8
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #4 on: November 09, 2013, 10:01:25 pm »
I'm still having no luck with my code when all the delay()s are changed to DigiKeyboard.delay()s (not even getting the constant value for range like I was before adding in the resistors). If I upload the DigiKeyboard example code though I have no issues. I must have overlooked something and I'll post if I figure it out.

septentriones

  • Newbie
  • *
  • Posts: 8
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #5 on: November 11, 2013, 04:26:22 pm »
Retested again. The DigiKeyboard sample still works fine and without the pull-up resistors I get the incorrect constant range printing out (like before). I also added in some additional print statements when testing with the pull-ups and I only get some of my print statements (and no range) but I'm not sure what might be causing the issue. I'm including my code and  I keep getting the following printout though the 0 does not always show up. Any ideas what might be going on here? I'm looking at TinyWireM.endTransmission(); because I see no print statement after.

0
Test
loc:1
loc:2
loc:3
0
Test
loc:1
loc:2
loc:3




Code: [Select]
/* Code for Arduino Uno R3 modified for Digispark
Assumes the sensor is using the default address
Sensor Connections:
Pin 7 to GND
Pin 6 to 5V
Pin 5 to SCL
Pin 4 to SDA
Requires pull-ups for SCL and SDA connected to 5V to work reliably
*/

#include "DigiKeyboard.h"                //included in order to debug
#include "TinyWireM.h"
//The Arduino Wire library uses the 7-bit version of the address, so the code example uses 0x70 instead of the 8-bit 0xE0
//I don't know if this statement holds true for TinyWireM

#define SensorAddress byte(0x70)
//The sensors ranging command has a value of 0x51
#define RangeCommand byte(0x51)
//These are the two commands that need to be sent in sequence to change the sensor address
#define ChangeAddressCommand1 byte(0xAA)
#define ChangeAddressCommand2 byte(0xA5)
 
void setup() {
 Serial.begin(9600); //Open serial connection at 9600 baud
 TinyWireM.begin(); //Initiate TinyWireM library for I2C communications with the I2CXL-MaxSonar-EZ
}
 
void loop(){
 DigiKeyboard.println(0);
 DigiKeyboard.println("Test");
 takeRangeReading(); //Tell the sensor to perform a ranging cycle
 DigiKeyboard.println("got here");
 DigiKeyboard.delay(100); //Wait for sensor to finish
 word range = requestRange(); //Get the range from the sensor
 DigiKeyboard.println("Range: ");
 DigiKeyboard.println(range); //Print to the user
}
//Commands the sensor to take a range reading
void takeRangeReading(){
  DigiKeyboard.println("loc:1");
 TinyWireM.beginTransmission(SensorAddress); //Start addressing
 DigiKeyboard.println("loc:2");
 TinyWireM.send(RangeCommand); //send range command
 DigiKeyboard.println("loc:3");
 TinyWireM.endTransmission(); //Stop and do something else now
}
//Returns the last range that the sensor determined in its last ranging cycle in centimeters. Returns 0 if there is no communication.
word requestRange(){
 DigiKeyboard.println("loc:4");
 TinyWireM.requestFrom(SensorAddress, byte(2));
 if(TinyWireM.available() >= 2){ //Sensor responded with the two bytes
 byte HighByte = TinyWireM.receive(); //Read the high byte back
 byte LowByte = TinyWireM.receive(); //Read the low byte back
 word range = word(HighByte, LowByte); //Make a 16-bit word out of the two bytes for the range
 return range;
 }
 else {
 return word(0); //Else nothing was received, return 0
 }
}
/* Commands a sensor at oldAddress to change its address to newAddress
oldAddress must be the 7-bit form of the address that is used by Wire
7BitHuh determines whether newAddress is given as the new 7 bit version or the 8 bit version of the address
If true, if is the 7 bit version, if false, it is the 8 bit version
*/
void changeAddress(byte oldAddress, byte newAddress, boolean SevenBitHuh){
 DigiKeyboard.println("loc:5");
 TinyWireM.beginTransmission(oldAddress); //Begin addressing
 TinyWireM.send(ChangeAddressCommand1); //Send first change address command
 TinyWireM.send(ChangeAddressCommand2); //Send second change address command
 
 byte temp;
 if(SevenBitHuh){ temp = newAddress << 1; } //The new address must be written to the sensor
 else { temp = newAddress; } //in the 8bit form, so this handles automatic shifting
 
 TinyWireM.send(temp); //Send the new address to change to
 
 TinyWireM.endTransmission();
}
« Last Edit: November 11, 2013, 04:30:57 pm by septentriones »

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #6 on: November 11, 2013, 07:25:58 pm »
Try commenting out Serial.begin and any other Serial calls - they are not being used and I'm wondering if they are conflicting with the I2C - actually it very likely is - the built in TX only software serial that Serial.begin would trigger is on pin 2 as well as the SCL line for I2C

septentriones

  • Newbie
  • *
  • Posts: 8
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #7 on: November 13, 2013, 11:16:05 am »
I commented out the Serial calls and I took readings with an oscilloscope and I seem to be sending requests just fine (I'm still using the 4.7K resistors). I still am only getting printouts before the TinyWireM.endTransmission(); call. Is there something that needs to be changed in the library for this to work properly? I'll include the current code I am using as well as the oscilloscope readings.



Code: [Select]
/* Code for Arduino Uno R3 modified for Digispark
Assumes the sensor is using the default address
Sensor Connections:
Pin 7 to GND
Pin 6 to 5V
Pin 5 to SCL
Pin 4 to SDA
Requires pull-ups for SCL and SDA connected to 5V to work reliably
*/

#include "DigiKeyboard.h"                //included in order to debug
#include "TinyWireM.h"
//The Arduino Wire library uses the 7-bit version of the address, so the code example uses 0x70 instead of the 8-bit 0xE0
//I don't know if this statement holds true for TinyWireM

#define SensorAddress byte(0x70)
//The sensors ranging command has a value of 0x51
#define RangeCommand byte(0x51)
//These are the two commands that need to be sent in sequence to change the sensor address
#define ChangeAddressCommand1 byte(0xAA)
#define ChangeAddressCommand2 byte(0xA5)
 
void setup() {
 //Serial.begin(9600); //Open serial connection at 9600 baud
 TinyWireM.begin(); //Initiate TinyWireM library for I2C communications with the I2CXL-MaxSonar-EZ
}
 
void loop(){
 DigiKeyboard.println(0);
 DigiKeyboard.println("Test");
 takeRangeReading(); //Tell the sensor to perform a ranging cycle
 DigiKeyboard.println("got here");
 DigiKeyboard.delay(100); //Wait for sensor to finish
 word range = requestRange(); //Get the range from the sensor
 DigiKeyboard.println("Range: ");
 DigiKeyboard.println(range); //Print to the user
}
//Commands the sensor to take a range reading
void takeRangeReading(){
  DigiKeyboard.println("loc:1");
 TinyWireM.beginTransmission(SensorAddress); //Start addressing
 DigiKeyboard.println("loc:2");
 TinyWireM.send(RangeCommand); //send range command
 DigiKeyboard.println("loc:3");
 TinyWireM.endTransmission(); //Stop and do something else now
}
//Returns the last range that the sensor determined in its last ranging cycle in centimeters. Returns 0 if there is no communication.
word requestRange(){
 DigiKeyboard.println("loc:4");
 TinyWireM.requestFrom(SensorAddress, byte(2));
 if(TinyWireM.available() >= 2){ //Sensor responded with the two bytes
 byte HighByte = TinyWireM.receive(); //Read the high byte back
 byte LowByte = TinyWireM.receive(); //Read the low byte back
 word range = word(HighByte, LowByte); //Make a 16-bit word out of the two bytes for the range
 return range;
 }
 else {
 return word(0); //Else nothing was received, return 0
 }
}
/* Commands a sensor at oldAddress to change its address to newAddress
oldAddress must be the 7-bit form of the address that is used by Wire
7BitHuh determines whether newAddress is given as the new 7 bit version or the 8 bit version of the address
If true, if is the 7 bit version, if false, it is the 8 bit version

void changeAddress(byte oldAddress, byte newAddress, boolean SevenBitHuh){
 DigiKeyboard.println("loc:5");
 TinyWireM.beginTransmission(oldAddress); //Begin addressing
 TinyWireM.send(ChangeAddressCommand1); //Send first change address command
 TinyWireM.send(ChangeAddressCommand2); //Send second change address command
 
 byte temp;
 if(SevenBitHuh){ temp = newAddress << 1; } //The new address must be written to the sensor
 else { temp = newAddress; } //in the 8bit form, so this handles automatic shifting
 
 TinyWireM.send(temp); //Send the new address to change to
 
 TinyWireM.endTransmission();

}
*/

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #8 on: November 13, 2013, 09:44:48 pm »
First of all I'm jealous of your scope access...

I'm stumped - only ideas I can come up with:

Try changing the delay to 1000 to ensure it completes and do DigiKeyboard.sendKeyStroke(0); right before range - sometimes  (some machines) after a delay the keystrokes stop registering if you don't send that.


gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #9 on: November 14, 2013, 06:50:45 am »
When I look at your scope-pictures and the datasheet of the MB1242 i have some questions:

At which voltage you are driving the MB1242?  The datasheet allows for 3V – 5.5V. 
When I look at the voltage-amplitudes from your scope, its about 2.8V. So I assume, that you may have a 3V power source for your sonar, and the pullups tied to that source.

For sure, you are running the digispark at 5V, because it is plugged to USB. 

As I2C needs to have at least 0.7 Vdd for HIGH and not more than 0.3Vdd for low, the I2C peak voltage in your scope should be at least 3.5V.

Can that be your problem?

regards
  .g

septentriones

  • Newbie
  • *
  • Posts: 8
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #10 on: November 14, 2013, 08:03:09 am »
Thank you for pointing that out gogol. I was powering the sensor from the 5v pin on the digispark (assuming that it was 5v) but I rechecked all the voltages and while I am getting 5v from my usb port, I am only getting 2.8 from the 5v pin. Is the diode on the digispark really causing this much of a drop? I'm wondering if I should jump over the diode (and just be sure not to ever connect an external power source while connected to usb) or something else because this seems like the reason that the sensor is not working. Suggestions?

EDIT: I happened to have one more digispark that I soldered together and everything seems to be working with it because I'm getting the proper voltage.
« Last Edit: November 14, 2013, 08:34:57 am by septentriones »

gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #11 on: November 14, 2013, 08:27:45 am »
I killed several of those diodes, when I played around with a digispark in the breadboard. I never realized why. I replaced them with a through-the-pin version.
See: http://digistump.com/wiki/_media/digispark/tutorials/removed-attiny.jpg?cache=

Replacing the with just a wire (as some people mentioned) is from my point of view to risky for the computer, especially when using that digispark in other projects with separate power.




septentriones

  • Newbie
  • *
  • Posts: 8
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #12 on: November 14, 2013, 08:44:43 am »
Right, after checking my supply of digisparks I have two that seem to be functioning fine and two that are broken. I'll replace the diodes on those when I get a chance. Thanks again for pointing out my voltage though, I completely overlooked it.  ;D

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #13 on: November 14, 2013, 01:56:34 pm »
Glad you got it working! If the two with bad diodes are new then I'm happy to replace them - just send us an email support at digistump dot com

We're looking at some more robust diodes for the future


septentriones

  • Newbie
  • *
  • Posts: 8
Re: Maxbotix Ultrasonic Sensor and Digispark
« Reply #14 on: November 14, 2013, 02:11:50 pm »
Thanks! One was new so I'll email support when I get a chance. I should have checked the voltage earlier but I'm glad that it was a straightforward issue and not some obscure problem.