PWM output not working when Servo activated

Hey there,
I have a BlendMicro and send with Android and BLE some data to my device to control LEDs and Servos. I have currently 2 “channels” and can control via pwm signal two different LEDs. The problem is, if I add the code for servos /change code (according to the library example) (btw: in the “pwm-only-version” the servo-library was already included)

I change the code that one output has a Servo attached, the remaining LED isn’t working anymore. (In both cases the servo-library is included).

Here is the code: (i guess only the beginning and end are of interest now, so scroll down;)

#include <SPI.h>
#include <EEPROM.h>
#include <boards.h>
#include <RBL_nRF8001.h>
#include <Servo.h>

#define PWM_PIN_1     9
#define PWM_PIN_2    10
#define SERVO_PIN_1  11
String sdata0 = "0";
String sdata1 = "0";
String sdata2 = "0";
String sdata3 = "0";
String sdata_all = "0";
int idata0 = 0;
int idata1 = 0;
int idata2 = 0;
int idata3 = 0;
unsigned int idata_all = 0;
String schannel = "0";
int ichannel = 0;

Servo Servo1;

void setup() {

  ble_begin();
  Serial.begin(57600);
  ble_set_name("BLEtest");

  Servo1.attach(SERVO_PIN_1);
  delay(5000);//time to open serial after connecting to computer

}

void loop() {





  while (ble_available()) {
    sdata0 = ble_read();//reading all data. it must be String. Data has 2-4 digits: 1st one always indicates "channel" (1-9), the following the (pwm) value. Android sends 4byte blocks: To send numbers bigger than 255, after 1st byte is "filled" (255) the 2nd get 1 and the 1st one starts at 0 again. then the second gets 2, and so on, till it reaches 255.
    sdata1 = ble_read();
    sdata2 = ble_read();
    sdata3 = ble_read();
    idata0 = sdata0.toInt();//convert it to int. need for math-function later
    idata1 = sdata1.toInt();
    idata2 = sdata2.toInt();
    idata3 = sdata3.toInt();
    idata_all = idata0 + (idata1 * 256); //+ (idata2 *512 + 65024) + (idata3 *1024); // "connect" data0 and data1 is quite easy, but didn't found out how to handle data2 and data3. Anyway, we don't need higher numbers (3 for pwm and 1-2 left for channel (max 60 channels possible - that's enough:D )
    sdata_all = idata_all; //converting back to string for reading "channel"
    Serial.println("sdata_all");
    Serial.println(sdata_all);

    schannel = sdata_all.charAt(0);//saving channel in int
    ichannel = schannel.toInt();
    Serial.println("channel");
    Serial.println(ichannel);
    sdata_all.remove(0, 1);//remove 1st digit, so just the value remains
    idata_all = sdata_all.toInt();//convert back to int :D
    Serial.println("data_all");
    Serial.println(idata_all);//print for control


    switch (ichannel) {
      case 1://if channel 1 do:
        analogWrite(PWM_PIN_1, idata_all);//write pwm output
        break;
      case 2://if channel 2 do:
        Servo1.write(idata_all);
        break;
    }
  }


  // Allow BLE Shield to send/receive data
  ble_do_events();



}

Blend Micro : http://redbearlab.com/blendmicro
Schematic : GitHub - RedBearLab/Blend: Arduino-compatible boards (Blend and Blend Micro) with BLE (Atmega32u4 + nRF8001).

The Bluetooth uses an SPI interface, so pin D0 and D1 are still available.

The Servo library uses Timer1 (I think).
The analogWrite for pin 9 and 10 uses also Timer1.

Could you use other pins for PWM ?
Pin 3 and 11 use Timer0.
Pin 5 use Timer3.
Pin 6 and 13 use Timer4.

You declare 6 String objects. Can you change that into normal text buffers ?

Koepel:
...
Solving Memory Problems | Memories of an Arduino | Adafruit Learning System

Great reference page! I especially like the DDJ reference.

From the Servo library documentation:

https://www.arduino.cc/en/Reference/Servo
"On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins. On the Mega, up to 12 servos can be used without interfering with PWM functionality; use of 12 to 23 motors will disable PWM on pins 11 and 12."

Sorry for late answer, but thank you. so stupid:D It was just that the pin 9 and 10 are not working as pwm when I use a servo.

Other problem:

I cleaned up a bit my code. With my phone I send 6-digit numbers. I receive it in 4 bytes. I think you know how it's working, but I will try to explain it with my small knowledge: byte0 counts till 255. When number gets bigger than that, byte1 = 1 and byte0 starts at 0 again. counts to 255 --> byte2 = 2 and so on. When number gets bigger than 65536 (256^2) byte2 will be used as well.
So - that's my way how to make one value again:
ldata_all = bdata0 + (bdata1 *256) + (bdata2 *65536);
while ldata_all is a long variable.

But some values just get mixed up.

Example below: first value is the sent one, the other is the "received" one.
50000-->-15536
65536-->65536 (equals 256^2)
600000-->600000
700000-->634464
999999-->999999

I just don't get it...Don't see a regularity in it.
The received bytes are definitly correct.
I tryed unsigned long, tryed "long ldata_all = 0L;" nothing changes.

byte bdata0 = 0;
byte bdata1 = 0;
byte bdata2 = 0;
byte bdata3 = 0;
byte bdata_all = 0;
long ldata_all;
int idata_all = 0;

void setup() {

  ble_begin();
  Serial.begin(57600);
  ble_set_name("BLEtest");


  delay(5000);//time to open serial after connecting to computer

}

void loop() {





  while (ble_available()) {
    bdata0 = ble_read();//reading all data. it must be String. Data has 6 digits: 1st one always indicates "channel" (1-9), the following the (pwm) value. Android sends 4byte blocks: To send numbers bigger than 255, after 1st byte is "filled" (255) the 2nd get 1 and the 1st one starts at 0 again. then the second gets 2, and so on, till it reaches 255.
    bdata1 = ble_read();
    bdata2 = ble_read();
    bdata3 = ble_read();

    Serial.println(bdata0);//print for control
    Serial.println(bdata1);
    Serial.println(bdata2);
    Serial.println(bdata3);

    ldata_all = bdata0 + (bdata1 *256) + (bdata2 *65536);// + (bdata3 * 16777216); // "connect" data0 and data1 is quite easy, but didn't found out how to handle data2 and data3. Anyway, we don't need higher numbers (3 for pwm and 1-2 left for channel (max 60 channels possible - that's enough:D )

    Serial.println("ldata_all");
    Serial.println(ldata_all);

Phone numbers are easier to deal with as text characters. Nobody ever needs to add two phone numbers.

…R

Actually…it’s not about phone numbers:)
It’s to control Servos/LEDs.
first two digits name the channel, while the other 4 name the microseconds for the servo (or any other value).
The next step is to convert it to a string, split the “two” parts and have two integers - channel and value.
You see that code in the first post

Bluetruck:
Actually...it's not about phone numbers:)

My mistake ...

Have a look at the examples, and especially the parse example in Serial Input Basics

...R

Hm, I don't think that is important for THIS issue. In general good information, yes, but I think I have a general problem with my thinking about variables.

the facts: I receive definitly correct data. The "formula" is also correct. I can take the received data and calculate it with my hand calculator, and I always get the correct value.
As shown in the examples: Apperently randomly I get wrong variables. It doesn't seem to be about the size.

So I have to ideas where my mistake may lie:
-arduino does not calculate the same way I do;)
-there is a issue with the variables (but long should be "big" enough anyway?!)

Bluetruck:
-arduino does not calculate the same way I do;)

Arduino (and all computers in general) does not calculate the same way you do. It has a limited space in which to hold a number. For instance:

byte a = 254;
byte b = a + 7;

Would it surprise you to find out that the value of b is now 5?

Also keep in mind that all the math is done on the right hand side of the equals BEFORE anything is assigned to the left hand side. SO it doesn't matter one little bit that the variable you're assigning to is a long, if all the variables on the right hand side of the equals are bytes or ints then you will still see rollover at those values.

unsigned int a = 65535;
unsigned long b = a + 5;

Now b has the value 4, because the math was done with unsigned int type and then the result was assigned to a long. Nothing about b being a long will affect the math that is done on the rhs of this equation.

unsigned int a = 65535;
unsigned long b = a + 5ul;

Now the ul tells the compiler that 5 should be treated as unsigned long. Now the math will be done with unsigned long and the result in b will be 65540.

Hey, thank you quite a lot. It seems to help;)
Just one question: Why is the UL/U/L actually behind the "5"? I mean, "a" is the integer that has to be used like a long. Or does this "suffix" apply for the whole right side?

The suffix only applies to the one thing that it is on. But by promoting just one thing on the RHS to unsigned long, now the whole thing has to be treated as unsigned long. Think about it, why does it matter if the a or the 5 is the one taking up 32 bits? You can't get rid of extra bits doing math, so as long as either one of them is 32 bits long then the result will have to be 32 bits. (keep in mind that any naked number like a 5 or a 62 will be treated as 16 bit unless it is already too big.)

If you wanted to make a an unsigned long you couldn't just add ul to it. That would make aul, now is that a variable named aul or a variable named a with a ul behind it. Compilers don't like ambiguity. So to make the a unsigned long you'd need a cast.

This would get you the same result.

unsigned long b = (unsigned long)a + 5;