Trinket AnalogRead jitter

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
MARKSE
 
Posts: 21
Joined: Mon Apr 24, 2017 4:09 am

Trinket AnalogRead jitter

Post by MARKSE »

Hi,

I've got a number of 5V Trinkets for a robotics project. At the moment I'm writing proof of concept code running with 2 pots, a servo and i2c connection to a Pi Zero W.

Code: Select all

#include "TinyWireS.h"
#include <avr/power.h>
#include "Servo8Bit.h"
#define I2C_SLAVE_ADDR  0x26            // i2c slave address (38)

Servo8Bit myServo;
int input1 = 2; // 'analogue' pin 2 - AKA digital pin 4. #4
int input2 = 3; // 'analogue' pin 3 - AKA digital pin 4. #3
byte number=0;
byte value=0;
int offset=0;

void setup() { 
   TinyWireS.begin(I2C_SLAVE_ADDR);      // init I2C Slave mode
   TinyWireS.onReceive(receiveEvent);
   TinyWireS.onRequest(requestEvent);
       if (F_CPU == 16000000) {
        // we are running at 16MHz
        clock_prescale_set(clock_div_1);
    }
    myServo.attach(1);  //attach the servo to pin PB1
    myServo.write(0);   //rotate to the 0 degree position
}

void loop() {
  myServo.write(value);             // tell servo to go to position in variable value
  TinyWireS_stop_check();
}

void receiveEvent(uint8_t) {
  number=TinyWireS.receive(); // "number" not used elsewhere just yet.
}

void requestEvent() {
   value = (analogRead(input1)/4);
   offset = ((analogRead(input2)-512)/8);
   value=value+offset;
   TinyWireS.send(value);
   myServo.write(value);
}
The Pi runs a loop to push a byte to the Trinket over I2C once every 500ms and read a value back and print it.
The pots have soldered connections, yet the analogRead() is returning numbers with a jitter. E.g. 192, 192, *5*, 192, 192, 193, 192.
Is a timer operation conflicting with the analogRead do you think? Any improvements I can make to the code to fix this or do I need to look at moving the servo function to a dedicated controller?

Regards,
Mark

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Trinket AnalogRead jitter

Post by adafruit_support_bill »

Servos are pretty noisy electrically. They can cause fluctuations in the supply voltage (which is also your analog reference voltage) as well as brush-noise from the motor.

Running the servos from a separate power source may help. You can also try doing some software low-pass filtering on the analog reads.

User avatar
MARKSE
 
Posts: 21
Joined: Mon Apr 24, 2017 4:09 am

Re: Trinket AnalogRead jitter

Post by MARKSE »

Hi, thanks for the reply. I've been doing some more experimenting, updated the sketch to only set the servo position within the loop. Even with the servo disconnected I'd still see the numbers jump. I spotted a potential pattern in the decimal and updated my Pi code to show me the numbers coming back in binary too. It made it obvious, the MSB is being dropped! The value from the read is coming back from the pots, the value written isn't being used at the moment. No matter where I put the pots the numbers jump out when bit 128 can nobbled. Does this sound like a timing issue with the I2C? I'm using TinyWireS.h

pos = analogRead(input1);
offset = ((analogRead(input2)-512)/8);
pos=(pos+offset)/4;
TinyWireS.send(pos);

Write. Read. Binary.
25 011 00001011
26 139 10001011
27 139 10001011
28 011 00001011
29 139 10001011
30 139 10001011
31 139 10001011
32 139 10001011
33 139 10001011
34 139 10001011
35 139 10001011
36 139 10001011
37 139 10001011
38 011 00001011
39 139 10001011
40 011 00001011
41 139 10001011
...
65 140 10001100
66 140 10001100
67 012 00001100
68 140 10001100
69 012 0001100
70 140 10001100
71 140 10001100
72 140 10001100
73 140 10001100
74 140 10001100
75 140 10001100
76 012 00001100
77 011 00001011
78 139 10001011
79 139 10001011

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Trinket AnalogRead jitter

Post by adafruit_support_bill »

I don't think it is dropping the MSB. I think it is just overflowing your byte value.

The ADC on the ATTiny85 is a 10-bit ADC. You are reading it into an 8-bit byte.

User avatar
MARKSE
 
Posts: 21
Joined: Mon Apr 24, 2017 4:09 am

Re: Trinket AnalogRead jitter

Post by MARKSE »

My code divides the (int) numbers from the analogRead() down so it should fit in the 8 bit byte. (Both pots will be mechanically limited to an area around the centre point.) If you look at the number sequence only the MSB is dropping. The LSBs are not changing in the sequence below. If it were overflowing a byte value I'd expect the byte value that remained to be consistent, maybe fluctuate by +/- 1 or 2 at the very most from the analogRead. Maybe it's the Pi at fault on the receiving side? I've no idea how to debug I2C at a low level, yet.

0025 011 00001011
0026 139 10001011
0027 139 10001011
0028 139 10001011
0029 139 10001011
0030 139 10001011
0031 011 00001011
0032 011 00001011

Current sketch:

Code: Select all

#include <avr/power.h>
#include "TinyWireS.h"
#include "Servo8Bit.h"

Servo8Bit myServo;

#define I2C_SLAVE_ADDR  0x26

int input1 = 2;
int input2 = 3;
byte number=0;
byte value=90;
int pos=0;
int offset=0;

void setup() { 
   TinyWireS.begin(I2C_SLAVE_ADDR);
   TinyWireS.onReceive(receiveEvent);
   TinyWireS.onRequest(requestEvent);
    if (F_CPU == 16000000) {
      // we are running at 16MHz
      clock_prescale_set(clock_div_1);
    }
    myServo.attach(1);
    myServo.write(90);
}

void loop() {
  myServo.write(value);
  TinyWireS_stop_check();
}

void receiveEvent(uint8_t) {
  value=TinyWireS.receive();
}

void requestEvent()
{
   pos = analogRead(input1);
   offset = ((analogRead(input2)-512)/8);
   pos=(pos+offset)/4;
   TinyWireS.send(pos);
}

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Trinket AnalogRead jitter

Post by adafruit_support_bill »

You've got several variations of the code there, so it is not clear what generated that output. But here you have "pos" defined as an int (16 bits)

Code: Select all

int pos=0;


And here, you assign it to a 10 bit value with the analogRead(), then add the value of "offset" to it. Then call TinyWireS.send() which will transmit 8 bits of that.

Code: Select all

void requestEvent()
{
   pos = analogRead(input1);
   offset = ((analogRead(input2)-512)/8);
   pos=(pos+offset)/4;
   TinyWireS.send(pos);
}

User avatar
MARKSE
 
Posts: 21
Joined: Mon Apr 24, 2017 4:09 am

Re: Trinket AnalogRead jitter

Post by MARKSE »

The code has been changed over time to try and find the thing that causes the inconsistency. It's nothing to do with power to the servo, I've run everything off a better supply and with the servo disconnected, no change. If the int is < 256 sending a bytes worth should be consistent should it not? I'll AND with 0xFF if you think not.

I'm begining to wonder if it's the I2C on the Pi Zero W sometimes getting confused about that bit, I2C sending MSB first. I'll get a Pi3 to experiment with, see if that helps.

Reading this TI doc I'm wondering if the handover from master to slave for a read is having timing issues.

http://www.ti.com/lit/an/slva704/slva704.pdf

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Trinket AnalogRead jitter

Post by adafruit_support_bill »

It is possible. A simple test of that theory would be to send a constant 0xFF and see if bits are dropping from that.

User avatar
MARKSE
 
Posts: 21
Joined: Mon Apr 24, 2017 4:09 am

Re: Trinket AnalogRead jitter

Post by MARKSE »

Hi! It's fixed, mostly. Adding this to the RPi /boot/config.txt did the trick, it being the master and providing all the i2c clocking.

dtparam=i2c_baudrate=400000

I suspect there's a timing issue going on between the Trinket/Pi. Running it at the faster i2c clock speed makes a) i2cdetect -y 1 *way* faster and b) stops the MSB clobbering. Instead of lots of errors I see maybe 1 in 1000.

Thanks for being my sounding board! Now I can go Trinket crazy :D
Regards, Mark

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Trinket AnalogRead jitter

Post by adafruit_support_bill »

Good to hear! Thanks for the follow-up.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”