Show Posts
Pages: [1]
1  International / Nederlands / Re: Bascom voor Arduino on: September 05, 2012, 11:50:12 am
Je kan best je bascom code op het Bascom forum posten als je hulp zoekt.
Daar zijn er veel meer mensen die met Bascom werken dan hier.
Maar beste... in Ticktock zeg je eerst "resetTtc als die groter is dan 490"... en later zeg je "zet bit als Ttc groter is dan 2000"... dat zal natuurlijk nooit voorkomen.

Jan Huygh
2  Using Arduino / Programming Questions / Re: My code needs Serial.begin to work but I do not need Serial support in my code on: August 21, 2012, 05:09:38 pm
The code now works... two things had to be done...
1) The array was incorrectly dimensioned in the beginning of the code (embarrassing)... I also changed the way the array is used in the OCR1B ISR.
2) In the OCR1A interrupt routine you needs to clear the interrupt. And to clear you need to write a 1 to the corresponding bit (so I write 255 to TIFR1) before you enable the interrupts again.

The now well working code
Code:
//Convenience macros
#define TC1_ConnectToPrescaler_8 TCCR1B &= ~((1<<CS12) | (1<<CS10)) ; TCCR1B |= (1<<CS11)
#define TC1_ClearOnCompareMatchWithOCR1A TCCR1A &= ~((1<<WGM11)|(1<<WGM10)); TCCR1B &= ~(1<<WGM13); TCCR1B |= (1<<WGM12)
#define TC1_EnableInterruptOnCompareMatchWithOCR1A TIMSK1 |= (1<<OCIE1A)
#define TC1_EnableInterruptOnCompareMatchWithOCR1B TIMSK1 |= (1<<OCIE1B)
#define TC1_DisableInterruptOnCompareMatchWith0CR1B TIMSK1 &= ~(1<<OCIE1B)

const byte PPM_Pin = 12;
volatile byte PPM_Progress = 0;
volatile word CHX_Pulse[8];

void setup () {
  pinMode(13,OUTPUT);
  pinMode(PPM_Pin, OUTPUT);
  TC1_ConnectToPrescaler_8; //1 count = 0,5 µs
  TC1_ClearOnCompareMatchWithOCR1A;
  TC1_EnableInterruptOnCompareMatchWithOCR1A;
  OCR1A = 40000;
  for (byte i = 0 ; i < 8 ; i++){
    CHX_Pulse[i] = 800 + i*200;
  }
}

void loop () {
}

ISR(TIMER1_COMPA_vect){
  digitalWrite(PPM_Pin, LOW);
  PPM_Progress = 1;
  OCR1B = 800;
  TIFR1 = 255;
  TC1_EnableInterruptOnCompareMatchWithOCR1B;
  digitalWrite(13,HIGH);
  digitalWrite(13,LOW);
  return;
}

ISR(TIMER1_COMPB_vect){
  switch (PPM_Progress) {
    case 1: case 3: case 5: case 7: case 9: case 11: case 13: case 15: case 17:
      digitalWrite(PPM_Pin, HIGH);
      OCR1B = OCR1B + CHX_Pulse[((PPM_Progress + 1)/2) - 1]*2;
      break;
    case 2: case 4: case 6: case 8: case 10: case 12: case 14: case 16:
      digitalWrite(PPM_Pin,LOW);
      OCR1B = OCR1B + 800;
  }
  PPM_Progress++;
  if (PPM_Progress == 18) {
    TC1_DisableInterruptOnCompareMatchWith0CR1B;
  }
  return;
}
3  Using Arduino / Programming Questions / My code needs Serial.begin to work but I do not need Serial support in my code on: August 21, 2012, 09:55:12 am
The code here below works fine. It generates a pulse place modulation signal with 8 channels.

HOWEVER

If you comment out the Serial.begin(9600) … it does not generate the last (the 8th) channel. It in fact becomes unstable … an 8th channel comes up and moves from a much too small to a much too big pulse and after that you have a perfect 7 channel PPM signal…and after a very long time the 8th channel comes up again.
 
Anyone who has a hint?… because I’ve now tried many things for 7 hours and I am lacking inspiration.

Jan Huygh

PS:  I had the Serial.begin in my code for debugging

Code:
//Convenience macros
#define TC1_ConnectToPrescaler_8 TCCR1B &= ~((1<<CS12) | (1<<CS10)) ; TCCR1B |= (1<<CS11)
#define TC1_ClearOnCompareMatchWithOCR1A TCCR1A &= ~((1<<WGM11)|(1<<WGM10)); TCCR1B &= ~(1<<WGM13); TCCR1B |= (1<<WGM12)
#define TC1_EnableInterruptOnCompareMatchWithOCR1A TIMSK1 |= (1<<OCIE1A)
#define TC1_EnableInterruptOnCompareMatchWithOCR1B TIMSK1 |= (1<<OCIE1B)
#define TC1_DisableInterruptOnCompareMatchWith0CR1B TIMSK1 &= ~(1<<OCIE1B)

const byte PPM_Pin = 12;
volatile byte PPM_Progress = 0;
volatile word CHX_Pulse[7];

void setup () {
  Serial.begin(9600);
  pinMode(PPM_Pin, OUTPUT);
  TC1_ConnectToPrescaler_8; //1 count = 0,5 µs
  TC1_ClearOnCompareMatchWithOCR1A;
  TC1_EnableInterruptOnCompareMatchWithOCR1A;
  OCR1A = 40000;
  for (byte i = 0 ; i<8 ; i++){
    CHX_Pulse[i] = 800 + i*200;
  }
}

void loop () {
}

ISR(TIMER1_COMPA_vect){
  digitalWrite(PPM_Pin, LOW);
  PPM_Progress = 1;
  OCR1B = 800;
  TC1_EnableInterruptOnCompareMatchWithOCR1B;
  return;
}

ISR(TIMER1_COMPB_vect){
  switch (PPM_Progress) {
    case 1: case 3: case 5: case 7: case 9: case 11: case 13: case 15: case 17:
      digitalWrite(PPM_Pin, HIGH);
      OCR1B = OCR1B + CHX_Pulse[PPM_Progress/2]*2;
      break;
    case 2: case 4: case 6: case 8: case 10: case 12: case 14: case 16:
      digitalWrite(PPM_Pin,LOW);
      OCR1B = OCR1B + 800;
  }
  PPM_Progress++;
  if (PPM_Progress == 18) {
    PPM_Progress = 0;
    TC1_DisableInterruptOnCompareMatchWith0CR1B;
  }
  return;
}
4  Using Arduino / Programming Questions / Re: What is the clean way to include an ISR in a library? on: August 21, 2012, 09:38:25 am
@ pYro_65
Thank you for the input. Reading your answer I had to look up a few terms to understand you. (All that means is that I’m obviously not so advanced is C either).
And indeed I intend to have only one instance so I will make the class a wrapper of static functionality and avoid that users need to initialize. But I will have to study a bit before I get that done.

@DuaneB
Thank you for your input. I will study the  pinchangeint and servo library in depth. I did look at your code and that was indeed comprehensive.
Nice site by the way… there is more on your site that I find very interesting (e.g. transponder lap timer)

@michael_x
You are right, that is how I intended it

@gardner
For me your input is not so “on topic” BUT I do understand why you posted it… it will help others who read this topic based on the title of the topic.

@ALL
I thought I had working code… but it turns out that my debugging help is needed in the code to make that one work...  I will make another post on that to keep the title of the post correct. And when that is fixed I will return to this post to hopefully show may code in library form using your advice. (Assuming it will be helpful for others who try the same in the future)

Jan Huygh
5  Using Arduino / Programming Questions / What is the clean way to include an ISR in a library? on: August 21, 2012, 02:21:27 am
I have a decent know how about C and microcontrollers but have only read a book on C++. That book was not microcontroller oriented and does not speak about integrating Interrupt Service Routines (ISR’s) in a C++ Class definition.

I have written a program for a high end RC transmitter specialized in surface racing (cars, boats and robots). I have written that code originally in C (Atmel Studio so GCC) and recently also in BASIC (BASCOM). Now I want to port my code to the Arduino.

The core of an RC transmitter is a Pulse Place Modulation (PPM) generator. I want to implement that PPM-generator as a library that defines a C++ class PPM_generator. I want to offer that Library to the Arduino community so that other people can also easily develop their own transmitter code but also to make my code easy to maintain.

Ultimately the PPM_gererator would be used from my main program using something like this
Code:
#include <PPM_generator.h>
PPMG PPM_Generator;   //Create an object from the Class
PPMG.init(4);        //Initialise the PPM generator for 4 channels (8 would be the maximum)
PPMG.pulse (Channel, Length); //Set the pulse for channel “Channel” to Length “Length”
My PPM generator uses Timer1 that is configured for timer reset at compare match with OCR1A. It uses two ISR’s:  One on OCR1A (to get a rock solid pulse train starting every 20 ms) and one on OCR1B that actually times the pulse length for each channel. Almost all the intelligence is inside these ISR’s so that is where all the variables are manipulated. (I have the working in an Arduino sketch)
In C it is common (since you cannot pass variables on to an ISR) to define the variables that are manipulated inside an ISR as global variables at the start of the program. I could do that here too and that works. However… I want to write clean code that is easy to maintain so I want to make the ISR’s use PRIVATE variables that are encapsulated inside the Class in the library. How do I do that?

Jan Huygh
6  Using Arduino / Project Guidance / Re: led output as an input on: August 10, 2012, 03:44:34 am
On the board with the leds that you want to monitor, connect your voltmeter to the ground and measure with the other lead of your voltmeter the voltage over the led when the led is on and of.
Assuming you will see a really low voltage when the led is off and a well over 2V voltaged when the led is on...
Connect the ground of the Arduino to the ground of the "to be monitored" board.
Set your input pin to input (default at stratup)
Use digital read ... chances are really high it will work.
If it would not work chances are high that the Arduino will always read a high (even when the led is off). If that is the case... connect a 10k resistor between the input pin and the ground on the Arduino (it shoud make it so that you read a lowwhan the led is off).

Jan Huygh
7  Using Arduino / General Electronics / Re: low side current sense help on: August 10, 2012, 01:35:52 am
Use a hall sensor . Allegro has a whole range of them. You can get them from digikey

http://www.digikey.be/be/en/ph/Allegro/acs712.html?WT.term=_cat%3Adigikey.be&WT.mc_id=Dynamic+Search+Ads&WT.medium=cpc&WT.campaign=Dynamic+Search+Ads&WT.content=text&WT.srch=1&type=&WT.source=google&cshift_ck=400b0950-ceff-4b5c-b786-3829ac6e886ecs4zwiSQW8

Super simple to use :
Connect the hall sensor in the current cirquit (will add virtually no resistance).
Apply 5V power supply
Read the voltage at the output via anolog inpyut pin on the Arduino.
Sensors include a 5A version.
Over 2 KV isolation.

I've used them to build a motor controller (24V with current limitation selectable between 10 and 100A)

Jan Huygh
8  International / Nederlands / Re: Bascom voor Arduino on: August 09, 2012, 10:56:59 am
Ik heb me net vandaag ingeschreven op dit forum. Met deze is dit mijn allereerste post.

Ik heb een hele tijd AVR's in C geprogrammeerd (AVR studio) en ben dan overgestapt naar Bascom omdat ik daarmee VEEL sneller werkende code kan schrijven. Ik heb uiteindelijk een ongelimiteerde versie van Bascom gekocht.
De grootste applicatie die ik daarmee geschreven heb is een  zender voor afstandsbedieningen (RC Transmitter), 30 A4-tjes text en code waarvan heel veel commentaar.

Nu heb ik me recent een Ardiuno aangeschaft en ben ik aan het proberen om mijn transmitter code daarop aan de praat te krijgen. In bascom neemt die code 20k in... ik hoop dat ik dat in een Arduino van 30k ook kan laden. (Zou in C toch minstens even efficiënt moeten zijn dan in Basic)

Ik kan in ieder geval zeggen dat ik het heel interessant vond om hier te lezen hoe ik Bascom code in een Arduino kan laden.

Mijn hoofdreden om een Arduino te kopen was dat er daar een heel goedkope (12 Euro) versie van bestaat (de mini of was het de nano) en dat je geen programmer nodig hebt om je code daarin te laden. Als ik er dan in slaag om mijn transmitter daarin te programmeren dan zouden er velen zijn die mijn transmitter ook zelf kunne bouwen wardoor ze voor minder dan 200 euro een behoorlijk high-end transmitter hebben.

Tenslotte wil ik ook nog meegeven dat de C++-gebaseerde Arduino taal HEEL attractief is vooral omdat er een set objecten is die klaar zijn voor gebruik. Als je ooit zelf een LCD driver in C hebt "moeten" schrijven dan weet je ook waarom ik Bascom zo leuk vond en waarom ik de Arduino nu ook zo geweldig vind.

Ik probeer nog deze avond mijn eerste library te (beginnen) schrijven: Een Pulse_place_modulation_signal generator, dat is de core van mijn transmitter.

Groeten,

Jan Huygh
Pages: [1]