Show Posts
Pages: [1]
1  Using Arduino / Programming Questions / Re: Leonardo Keyboard Volume Control Help on: June 13, 2013, 11:14:34 am
Sorry about the slow reply - I had notifications turned off, and then left the planet. smiley

Unfortunately, I reverted my code, but here is what you can do if you want to test it out:

Open the file:   Arduino-Install-Directory\hardware\arduino\cores\arduino\HID.cpp

Find the function:   Keyboard_::press  (and Keyboard_::release) in that file

Copy & paste that function, rename it to "press_direct", and remove the top portion of the code that tests for  k >= 136, and setting modifiers, etc.  Then you'll need to open USBAPI.h file, and find the class declaration for Keyboard_, and add a new function definition for your new "press_direct" function.

Sorry for not being able to just copy the code over, but this will get clobbered anytime you install a new version of the arduino code, and I'm not on the latest version.
2  Using Arduino / Programming Questions / Re: Leonardo Keyboard Volume Control Help on: September 29, 2012, 12:09:21 pm
I'm looking to do the same thing - I've made progress, but still can't get it to work.

If you take a look at the hardware/arduino/cores/arduino/USBAPI.h file, it lists out some #defines for button presses:
Code:
#define KEY_LEFT_CTRL 0x80
#define KEY_LEFT_SHIFT 0x81
#define KEY_LEFT_ALT 0x82
#define KEY_LEFT_GUI 0x83
#define KEY_RIGHT_CTRL 0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT 0x86
#define KEY_RIGHT_GUI 0x87

#define KEY_UP_ARROW 0xDA
#define KEY_DOWN_ARROW 0xD9
#define KEY_LEFT_ARROW 0xD8
#define KEY_RIGHT_ARROW 0xD7

If you compare this to the USB specification (http://www.freebsddiary.org/APC/usb_hid_usages.php), you'll find they don't match:

Code:
0x4E Keyboard PageDown
0x4F Keyboard RightArrow
0x50 Keyboard LeftArrow
0x51 Keyboard DownArrow
0x52 Keyboard UpArrow

Code:
0xE0 Keyboard LeftControl
0xE1 Keyboard LeftShift
0xE2 Keyboard LeftAlt
0xE3 Keyboard Left GUI
0xE4 Keyboard RightControl
0xE5 Keyboard RightShift
0xE6 Keyboard RightAlt
0xE7 Keyboard Right GUI

If you take a look in hardware/arduino/cores/arduino/HID.cpp file, in the 'press' function, you see this:

Code:
size_t Keyboard_::press(uint8_t k)
{
uint8_t i;
if (k >= 136) { // it's a non-printing key (not a modifier)
k = k - 136;
} else if (k >= 128) { // it's a modifier key
_keyReport.modifiers |= (1<<(k-128));
k = 0;
} else { // it's a printing key
k = pgm_read_byte(_asciimap + k);
if (!k) {
setWriteError();
return 0;
}
if (k & 0x80) { // it's a capital letter or other character reached with shift
_keyReport.modifiers |= 0x02; // the left shift modifier
k &= 0x7F;
}
}

My first gripe - As a programmer, mixing decimal notation and hex notation is a huge pain.  136=0x88 - which is means that the "KEY_LEFT_CTRL" block of #defines will be caught there.  They call these 'Modifiers'.  128=0x80 - anything that falls below this is a standard ASCII key, and they look it up to find the HID code.

The reason they do this is so you can do something like "Keyboard.print("A")" and it'll press the 'A' key.  Very helpful for printing text, very NOT helpful if you want to press any old key on the keyboard.

What we want to do is press these keys:

Code:
0x7F Keyboard Mute
0x80 Keyboard Volume Up
0x81 Keyboard Volume Down

But if the code is going to subtract 136 (0x88) from them, it is literally impossible to get it to work (with the current 'press' code).  Essentially you're limited to only printing the first 256-136 = 120 keys - from 0x00->0x78.  JUST SHORT of what we need!

Since that is the case - I went ahead and made some new functions.  I made a press_direct and release_direct, which don't do any fiddling with the numbers, they just send it out as-is.  I tested my code by passing in the real HID values for letters, and it printed them as expected.  Unfortunately - the volume up/down/mute functions STILL don't work!!   smiley-mad

According to some sources, Windows just doesn't implement the functions in this way.  So if the application your sending the keys to will read them, it'll work, but Windows won't pick it up directly.  Linux and OS X will apparently work fine.
3  Using Arduino / Sensors / Re: Need help with analog input for AttoPilot voltage & current sensor on: August 23, 2012, 12:59:07 am
OK - I had some time to test tonight.

I checked the voltage between the AttoPilot ground and the actual ground wire that plugs into the power supply - its around 2mV.
Then I checked the voltage between the power supply ground wire and the USB shield wire - about 7mv.  This is with the arduino disconnected from the AttoPilot sensor (because it could mask the ground loop).

THEN... I checked the voltage between the power supply ground wire and the arduino ground - and its 32mv.  YIKES!  And this makes no sense - I thought the USB shield and the ground should be exactly the same, but I guess not!

I took a wire with alligator clip ends, clipped one to the main ground wire, and another to the arduino ground pin, it drops the voltage difference down to 2mV.  When I do this the accuracy of the reading gets better, though.  Actually power supply usage is around 1.2A (I removed some stuff from the PC to make sure they weren't causing issues) and when I connect the ground wire the sensor reading goes from 0.4-0.5A up to .7-.75A.

Actual sensed voltage on the arduino is now 0.03v, my multimeter on it says 0.033v.  The expected reading should be more like 0.045mv, so it definitely now seems like the ground issue is resolved, but I think my AttoPilot sensor is bad. smiley-sad
4  Using Arduino / Sensors / Re: Need help with analog input for AttoPilot voltage & current sensor on: August 22, 2012, 02:26:25 pm
Yes, I'm already using the 1.1v internal reference.  The current and voltages I am dealing with are significantly less than the 50 volts and 90 amps that the sensor puts out at 3.3v, so scaling down to 1.1v lets me get much finer resolution.

I'll definitely check to see if there is any voltage difference between the ground pin on the sensor and the ground pin on the arduino.  If there is, that definitely means something bad will happen. smiley

If that is indeed the case, I'll see if I can just not plug in the ground wire and see what happens, or I will try and narrow down where the ground fault is.  I would expect the incoming ground, M4-ATX ground, PC ground and USB ground to all be connected, but maybe not.
5  Using Arduino / Sensors / Re: Need help with analog input for AttoPilot voltage & current sensor on: August 22, 2012, 12:00:09 pm
I guess I didn't give much background on the overall setup of what I'm doing... so let me explain smiley

I am making a CarPC - it will eventually be running off of batteries in my car, and goes through a DC-DC power supply (called an M4-ATX, it's an automotive PC power supply).  On the bench right now I am using a 15 amp AC-DC power supply plugged into the AttoPilot voltage & current sensor, which is then plugged into the M4-ATX power supply, which powers the computer.  The computer is an Intel Core i5 box, and the arduino is plugged into one of its USB ports.  The 3 pins from the AttoPilot are run directly into the arduino A0, A1, and GND pins.

I suspect that near the PC it is quite a noisy (electrically) environment, and that may be causing some of the issue.  I'm also using regular male-male jumpers and not a shielded cable.

Originally I was having just a hell of a time getting anything useful from the setup, but the issue was that I was using the arduino plugged into my main PC to read the sensors, and the grounds were different (as you said), and it was causing the readings to be all over the place.
6  Using Arduino / Sensors / Need help with analog input for AttoPilot voltage & current sensor on: August 22, 2012, 01:14:00 am
I'm using this AttoPilot current & voltage sensor:

https://www.sparkfun.com/products/9028

The sensor has three pins - one is ground, one is voltage, and one is current.  I have the voltage & current pins each going into the arduino on analog ports 0 and 1.  I am setting AnalogReference to internal, so I am sensing @ 1.1v.  The voltage value is coming in -perfectly-.  I am running off a 13.8v AC-DC converter, and it gives me the same results as my multimeter - about 14v.  I have used an automotive fuse tester to test current running through the circuit, and it is saying there is 1.4A running through the sensor.  The sensor should scale 89.4A to 3.3v, so the sensor's current line should be ~52mv.  My multimeter is reading 55mV when I test right from the sensor, but when I test it after about 8 inches of wire it reads about 52mv.  The arduino is sensing a value of about 30, or about 32mv.

Any ideas how I can get the arduino to match up with the readings of my multimeter at the source?  I need to be able to run this sensor about 10 feet away from the arduino, so I picked up a shielded stereo audio cable - will that work or am I going to need something else?

Thanks for any info you can provide!!

-Bill
7  Using Arduino / Project Guidance / Re: Is it possible to have a stuck relay? on: August 06, 2012, 06:11:29 pm
You -must- use a transistor of some kind to power the relay.  There is just no way around it.  Even if you can get it to work on the bench, it won't work for long, and you'll end up frying your arduino.

It's a 20 cent part.

http://arduino.cc/playground/uploads/Learning/relays.pdf
8  Using Arduino / Networking, Protocols, and Devices / Re: Issues with I2C - data returned is weird... on: August 04, 2012, 05:42:00 pm
So, about 5 minutes after I posted this I found the problem. smiley

Code:
bool I2CReadRegisters( byte address, byte reg, byte bytes )
{
  // Select the register
  Wire.beginTransmission(address);
  Wire.write(reg);
  if( Wire.endTransmission() != 0 )     <-- ISSUE IS RIGHT HERE!!!!
  {
    Serial.print("I2CReadRegisters( Address=0x");
    Serial.print(address, HEX);
    Serial.print(", Register=0x");
    Serial.print(reg, HEX);
    Serial.print(", NumBytes=");
    Serial.print(bytes, DEC);
    Serial.println(") - failed at endTransmission");
    return false;
  }
  /* Request 'bytes' byte*/
  Wire.requestFrom(address,bytes);
  while( Wire.available() < bytes );
  return true;
}

The line:   if( Wire.endTransmission() != 0 )   The problem is that Wire.endTransmission takes an optional parameter ("stop") that defaults to true.  I guess some I2C devices will work fine either way, and some will not work the way it's written.  The fix is to pass in "false":

 if( Wire.endTransmission(false) != 0 )

After that - everything works. smiley
9  Using Arduino / Networking, Protocols, and Devices / Issues with I2C - data returned is weird... on: August 04, 2012, 11:55:08 am
I'm trying to get my arduino up and running with a 3-axis magnetometer (HMC5883L) and 3-axis accelerometer (MMA8452) over I2C.  When I connect up the magnetometer I get mostly decent data - but the "IDENTIFIER" registers don't return the right data, and it seems like the actual data returned from the magnetometer may be bad.  The values seem strange, but it is definitely responding to movement, but if I rotate about the Z axis, the Z value changes - which shouldn't happen.  The accelerometer is just completely out of whack.  If I print out the entire register set, the status register has 0xFF, rather than 0x00, and then all the other registers are 0xEC, 0xE6, 0x05, 0x00 - repeating.  It makes no sense.  I can re-read the same register and get totally different results each time.  Now - the particularly strange part is that if I have my loop read the 6 bytes of accelerometer data and print out the X,Y,Z values - the Y value is completely correct... But the others are whack.  And if I read them individually, they're all bad. (usually returning 0 or 0x0F)

Anyway - I am not sure what to do next to debug this.  I know data is going out and coming back in, but the data returned is just inconsistent.  I am using a logic level converter to switch between 5v and 3.3v, and I am using 4.7k pullups.  I've tried changing the pullups, I've tried putting pullups on the 5v side, I've tried removing one I2C device and using the other, etc.  Any tips would be much appreciated!!  Here are some code snippets:

Code:
// I2C Addresses:
#define COMPASS 0x1E       //0011110b, I2C 7bit address of HMC5883L 3-Axis Magnetometer
#define ACCELEROMETER 0x1D //0011101b, I2C 7bit address of MMA8452Q 3-Axis Accelerometer

bool I2CReadRegisters( byte address, byte reg, byte bytes )
{
  // Select the register
  Wire.beginTransmission(address);
  Wire.write(reg);
  if( Wire.endTransmission() != 0 )
  {
    Serial.print("I2CReadRegisters( Address=0x");
    Serial.print(address, HEX);
    Serial.print(", Register=0x");
    Serial.print(reg, HEX);
    Serial.print(", NumBytes=");
    Serial.print(bytes, DEC);
    Serial.println(") - failed at endTransmission");
    return false;
  }
  /* Request 'bytes' byte*/
  Wire.requestFrom(address,bytes);
  while( Wire.available() < bytes );
  return true;
}

bool I2CWriteRegister( byte address, byte reg, byte value )
{
  Wire.beginTransmission(address);
  Wire.write(reg);
  Wire.write(value);
  if( Wire.endTransmission() != 0 )
  {
    Serial.print("I2CWriteRegister( Address=0x");
    Serial.print(address, HEX);
    Serial.print(", Register=0x");
    Serial.print(reg, HEX);
    Serial.print(", Value=");
    Serial.print(value, HEX);
    Serial.println(") - failed at endTransmission");
    return false;
  }
  return true;
}

inline void ReadAccelerometer()
{
  // Only request the accelerometer data every 1500ms
  static unsigned long s_lastUpdateTime = 0;
  unsigned long now = millis();
  int delta = now - s_lastUpdateTime;
  if( s_lastUpdateTime != 0 && delta < 1500 )
  {
    return;
  }
  s_lastUpdateTime = now;
 
  Serial.print("Accelerometer: ");
 
  // Request 6 bytes, starting at register 0x01
  if( I2CReadRegisters(ACCELEROMETER, 0x01, 6) )
  {
    static char axis[] = {'x','y','z'};
    for(int i=0; i<3; ++i)
    {
      char value = Wire.read();
      Wire.read(); // Throw 2nd byte away.
      Serial.print(" ");
      Serial.print(axis[i]);
      Serial.print("=");
      Serial.print(value, DEC);
    }
    Serial.println("");
  }
 
  I2CReadRegisters(ACCELEROMETER, 0x01, 1);
  char value = Wire.read();
  Serial.print(" X=");
  Serial.print(value, DEC);
 
  I2CReadRegisters(ACCELEROMETER, 0x03, 1);
  value = Wire.read();
  Serial.print(" Y=");
  Serial.print(value, DEC);
 
  I2CReadRegisters(ACCELEROMETER, 0x05, 1);
  value = Wire.read();
  Serial.print(" Z=");
  Serial.println(value, DEC);
}

inline void ReadCompass()
{
  // Only request the compass every 500ms
  static unsigned long s_lastUpdateTime = 0;
  unsigned long now = millis();
  int delta = now - s_lastUpdateTime;
  if( s_lastUpdateTime != 0 && delta < 500 )
  {
    return;
  }
  s_lastUpdateTime = now;
 
  // Request 6 bytes, starting at register 0x03
  I2CReadRegisters(COMPASS, 0x03, 6);
 
  // Read the data
  Serial.print("Compass: X=");
  int value = Wire.read()<<8;
  value |= Wire.read();
  Serial.print(value);
 
  Serial.print(" Y=");
  value = Wire.read()<<8;
  value |= Wire.read();
  Serial.print(value);
 
  Serial.print(" Z=");
  value = Wire.read()<<8;
  value |= Wire.read();
  Serial.println(value);
}

And some sample output when I've got it only reading the accelerometer:
Code:
Accelerometer:  x=-1 y=-28 z=0
 X=0 Y=0 Z=15
Accelerometer:  x=-1 y=-28 z=0
 X=15 Y=15 Z=15
Accelerometer:  x=-1 y=-28 z=9
 X=0 Y=0 Z=0
Accelerometer:  x=-1 y=-28 z=0
 X=0 Y=15 Z=15
Accelerometer:  x=-1 y=-28 z=0
 X=14 Y=14 Z=14
Accelerometer:  x=-1 y=-28 z=0
 X=0 Y=15 Z=15
Accelerometer:  x=-1 y=-28 z=0
 X=0 Y=15 Z=15
Accelerometer:  x=-1 y=-28 z=0
 X=15 Y=15 Z=15
Accelerometer:  x=-1 y=-28 z=0
 X=0 Y=0 Z=15
^-- Note that the y=-28 is correct, but the others are not.
Pages: [1]