Saturday, 3 April 2010

final finish is a fact

After 2.5 years of work I finally reached my endpoint.

The last 3 months I had to solve a couple of issues in order to get a stable running system. I had to solve a few software bugs in the first place. But also some minor hardware adaptions were indispensable. Here is a list of things necessary to stabilize my project:

Software:
  • I2C end of buffer issue
  • I2C graceful stop
  • Blocking BKP domain
  • Test on external data values
  • BKP rework
  • ADC rework to capture temp sensor
 Hardware:
  • Component change opto 3023 into 3052
  • Opto led resistor 390 into 220
  • Triac SW type into CW type

Source code browse (read only):
http://code.google.com/p/triosdomotica/source/browse/
Subverion repositry:

svn checkout http://triosdomotica.googlecode.com/svn/trunk/ triosdomotica-read-only
 
System up and running:

http://www.youtube.com/watch?v=ZeqUAfePn74

This is my last post in this blog title. But I will continue to write some more in my other blog topics which cover some subsections of this project in more detail.


Special thanks to :

  • Ronny Suy ( hardware )
  • Michel Bari ( emergency repairs )
  • Google team ( resources )
  • Richard Barry ( freeRtos )
  • STM 32 forum ( cortex )

 And last but not least to all readers of this blog thanks for the interest.
 


Saturday, 14 March 2009

master with oled

First of all still very proud on this nice design made by my friend ! It was a good development kit to learn all things on the AVR. So the master was ment to be a target to change some slave parameters using my own one wire protocol. The purpose was to us the OLED display to give in the values. My one wire code was finished first and it coudn't test time being. But as soon as I implemented the slave state machine I finally could see the results. At first it was a bit tuning but after all that the concept worked very quickly without any major problems. On the picture you can see the master standing right next to the OLED display. At the right of the master you can see my 2 slaves. Again for any code snippets on the one wire refer to my code corner because this blog is not the place to format code in.
The second picture shows the OLED graphics. Programming it was fairly easy to do. The first step you need to do is transfer the init code out of the datasheet into your C code. Next the start of the init snippet:

// init the ports

DDRC = 0b11111111;
PORTC = 0b11111111;
DDRB = 0b00011111;
PORTB = 0b11111111;
DDRA = 0b11100000;
PORTA = 0b11111111;

PORTB = 0b11111110; // reset the oled
_delay_ms(1); // spec says wait a bit here
PORTB |=0b00000001; // unreset the oled

// general init commands out of spec
// TODO must be documented in detail

write_oled_command(0x02);
write_oled_data(0x01);
....

I wrote some helper functions for writing the command and data bytes to improve the readability of the code. When you succeed in the init the OLED will give you a screen full of noise pixels but at least you sure it's working. The purpose of the OLED screen was to give the user the ability to do some general parameter set up for the slaves. So I started to think on a possible interface for the little 160x128 pixeels display. The idea came up to use icons as a menu system. Of course the icons we all know on our computers today haven't the right format for the display. No problem for me as I can write some simple python scripts. I wrote a script that converts a extension ICO file to some raw binary data for the display. Code can be viewed at my code corner. With this script I can transfer 16x16, 32x32 or even 48x48 size icon files. The icons must be in 24 bit RGB although I have only 18 bits the last 2 bits are simply not taken into account. I only take the RGB data without the transparency information which I don't need. You can see the result of a converted 32x32 icon on the picture. This format suits very well and I can get 5 icons on one row and I have 4 rows so 20 icons in total. My intention was to draw a red rectangle over the icon to notice the user it's selected when using the 5 function mini joystick which is positioned right under the display. The only limitation I had was the amount of program flash to put in the raw icon byte arrays. I used the special gcc #pragma to locate the array into flash like this:

const uint8_t PROGMEM icon[3072] = {
0x3e,0x9a,0xde,
0x99,0x00,0x00,
0x99,0x00,0x00,
0x99,0x00,0x00,
0x99,0x00,0x00,
......

So as you can see a 32x32 icon takes already 3072 bytes in flash. But still possible to play with 15-18 icons depending on the program code size. To build a rich user interface this is definitly to less. I didn't wrote any code for the mini joystick as I was busy on the move from AVR to CORTEX. So that will be postponed to my new master based on the CORTEX core. Also here the STM32 offers a wide variety on targets that can have up to 512k on program flash. Indeed with 512k bytes you build a much nicer user interface for this oled display than with the AVR. Playing around with 80 different icons is no problem at all. That's basically it what I needed to tell you on my AVR experience.

I linked the TRIOS blog project on this target but in fact it's not quit correct anymore as I 'd changed my target now to ARM CORTEX. I decided to continue in that blog rather than here because all I will write next will be very closely linked to the CORTEX. So please for follow up on this reffer to:

http://guyvo-cortex.blogspot.com/

As the concept gets more and more to it's final stage now, it becomes time to build the PCBs. Due to the fact this has nothing todo directly with software I will open a brand new blog for it as soon as the first layouts starting to get some shape.

http://guyvo-dimmers.blogspot.com/

Enjoy !

change of processor ?

Like I told you in the previous blog I still had to find a suitable processor to implement the FIR filter. This means basically having enough performance to do a FIR calculation within the sample rate. I knew that a DSP was not reachable so I had to continue looking for a reasonable alternative with respect to speed , price and software availability. One day my eye felt on the cortex STM32. A friend of mine was already experimenting this target and he told me that the cortex was indeed a great core. I did some additional searches on software (IDE, libraries ,..) and it seemed that this was very promising. I saw that the RIDE7 environment (raisonance) was totally free of charge. It works with a gcc distribution of codesourcery and can work under windows. Meanwhile I searched also for a starter kit and found exactly what I was looking for at www.olimex.com. Cherry on the cake was that the ST people also wrote a DSP extension library for the cortex. That seemed very promising to me. I ordered the development board already.

In my previous blog I also spoke a bit on my FIR simulation. If you are interessed in the python code you can get it via my publishing corner:

http://sites.google.com/site/guyvo67/


At the picture on the left you can see the main sinus with the CAB signal on. This was the first thing I did reproducing the signal that caused the flickering as realistic as possible. The drawing was done with a simulated frequency of 40khz. Now I had my input signal it was time to integrate the FIR calculation. I experimented first with the java applet to get an idea on bandwidth and amount of taps. Than I copied the tap values into my python simulation. The calculation for FIR is rather simple. They exist out of set of MACs.(multiply/addition accumulations) So it was pretty easy in python to make the MACs. On the second picture you can see the result taken from a test with 20000 points and weak 6 order tap. In blue you can see the filtered signal which was already pretty nice for a start. I noticed that with increasing the taps you also increase the phase shift. But this shift is constant over the all signal. This can be considered as great advantage as I had to trigger the zero point most accurately. This effect can be seen on the third picture.

At that point my brand new development board was arrived. you can take a look at it on my cortex dedicated blog:

http://guyvo-cortex.blogspot.com/

My first thing I did with the cortex was as you could guess dive into the DSP function library. I did some quick tests using the RIDE simulator on performance. That moment made me very happy because it was only 7µs to calculate a 32 tapes FIR filter !!! At that particular time I was 100% sure to change my target from AVR to the CORTEX STM32 running on 72MHz. If you are curiuos on the real tests and how I did it you must switch to my cortex blog. So because the AVR story is almost ended here I will finish writing a next short blog on the master with OLED display.

Sunday, 8 March 2009

dimmer results

(click on the picture to view in full size)
I had to do a little bit of tuning at first with respect to the timings but at the end I had a very good working dimmer. The only pain in the ass was the CAB signal send by the net distributor. This signal comes when traffic lights or day/night tariff needs to switch on/off. In the case of Belgium and in my area this is 1347Hz. Although this is only 5% of the nominal 230V supply this causes heavy flickering. This was definitely something I didn't want in my final design. On the picture at the left you can see the error of the opto coupler. I noticed that this can be as far as -400µs + 400µs. Of course this phenomenon lets it
self see without a doubt. So I had to search for a solution. I first thought about simply putting an analogue filter network but this cause to many phase shifts and is difficult to get stable if you must go to 10 order and more. Yes this thing kept me going for about 3 mounts believe me. Second approach was putting a highly optimized crystal ( 0.3 ppm ) I tried to synch not on the zero cross but only on that crystal. Again this was a no go. The frequency of the net can vary between 49.8 - 50.2 in a few 10 seconds depending on area. So my crystal was far to secure to do the synchronisation. The lamp faded away and came back on again in about 10 to 20 seconds. I did a lot of try outs in software with partial synchronisation but still the flickering was there. After all that bad news, I started to read documents that told something about this topic. Lots of them. I even contacted a professor at the university of Idaho. He sent me a paper on optimizing a zero crossing. It was based on a PLL approach. I study the document but it had to many questions to even thinking on implementing it. But it gave me some new relief and hope. In between my searches I saw a lot about DSP processors. These things are very powerful especially for digital filtering. One disadvantage : those things are very expensive to buy in the form of a development kit. Meanwhile I had my focus now on trying to digitally filter the 1347Hz. Coincidently I just started to learn the python language and I saw in one of the libraries the plot.py. I started to experiment and wrote a program based on my theoretical point of view. I soon found out that indeed it could be done using a digital FIR ( Finite impulse response ). On the third picture you can see my simulation in plot python. So i artificiality generated the sin wave of 50hz + 1347HZ as the source signal. I calculated the factors using a helper program as java applet and can be found :

http://www.dsptutor.freeuk.com/FIRFilterDesign/FIRFilterDesign.html

I did a lot of testing with several number of taps and sampling rates. But at least I was very sure that this must be feasible. There was just one question to answer : which processor can handle these calculation and is also cheap enough to afford ?

Be my guest in my next blog that will be fully dedicated on this topic.

sequel 3 to slave concepts

4. handling one wire protocol with master

First of all I post my document link again where you can find the complete analyse and code:

http://sites.google.com/site/guyvo67/

(LOWBP.PDF)

I was lucky to have my analyse on paper first to implement the state diagram. It was very helpful. To fully test the protocol I had to program the master as well. But I come back on that later on. I used the ICP ( input capturing ) on the AVR to measure my timings. Below you can see how the timer needs to be setup:

/*! ********************************************
SetTimerOneWire
Preparing TIMER 0 16 bit for one wire capture
no prescale --> counting unit = 1\F_CPU

minimum unit: 12.8 MHz 78ns

maximum units: 12.8 MHz 5,1ms

@note
16 bit writing first high than low value
16 bit reading first low than high value

************************************************/
void SetTimerOneWire (void)
{
/// TIMER 0 enable ICR mode in 16 bit
TCCR0A = _BV(TCW0) | _BV(ICEN0);

/// TIMER 0 prescale value no prescale
TCCR0B = _BV(CS00);

/// TIMER 0 interrupt mask ICR
TIMSK |= _BV(TICIE0);

/// TIMER 0 starting point
TCNT0H = 0x00;
TCNT0L = 0x00;
}

So the timer is set up to handle measurements between 78ns and 5,1ms. As I put my one wire timings between 10µs-1ms this is more than precise enough to do the job. The last code snippet I want to show you is that of the interrupt itself. It works very closely together with the state machine implementation but again please refer to the document to view to full master/salve implementation. In the interrupt routine we handle the input capture measurements depending on the edges. We evaluate the measured values with our defined timing constants known by slave as well as master. Depending on the value I assign a global value to an enumeration that will be later used by the state machine to make appropriate decisions. Also here very straightforward code:

ISR(TIMER0_CAPT_vect)
{
if ( bit_is_clear(PINA, PA4) )
{
TRIGPOSEDGE;
RESTARTTIM0;
onewirepulse = INTIMING;
}
else
{
TRIGNEGEDGE;
ICRVALUE(icp);
if ( icp < onewidth )
{
onewirepulse = ONEPULSE;
}
else if (icp < zerowidth )
{
onewirepulse = ZEROPULSE;
}
else if (icp < resetwidth )
{
onewirepulse = RESETPULSE;
}
else
{
onewirepulse = ERRORPULSE;
}
capinterrupt = SIGNALED;
}
}

To be honest this was the most difficult thing to program with respect to the slave concept. But I managed to write it and test it and it worked ! I will dive a little deeper on those tests when I write something about the master. The one wire is actually optional for this design but it gives a nice added value.

My next blog will cover the overall results of this dimmer design.

sequel 2 to slave concepts

3.handling button actions:

To capture a button state change you have two option or you take a poll approach or you do it by interrupt. As I'm an interrupt lover I took the second option. On my AVR development board the EXT0 pin was used for connecting a button or switch. If you use the EXT0 you have the possibility to trigger on positive or negative edge or both. In my case I triggered the positive edge. This depends a bit on how you connect your button pulled up or not. The code of course to do that is more than simple:

ISR(INT0_vect)
{
interrupt0=SIGNALED;
}

The
interrupt0 flag I used is treated in the idle main loop. ( so a little polling anyway ) It's very important that you test the signal on any glitches or faults. The best thing you can do is bringing a delay loop in action as soon as you triggered a state change. If the signal is still stable and correct after the delay you can go ahead and treat the change as you wish. But let me copy in my code snippet here to make things clear it's sufficient self describing as you will notice reading it. Sorry for the layout , the indents are not correctly put, but it has only two levels and is not of much importance for the concept. ( HTML don't like tabs either ;-)

void TriacStep ( void )
{
if ( interrupt0 == SIGNALED )
{
// turn off INT after neg edge
DISABLEINT0;

// poll pin on remain clear
// in case of glitch abort while loop
while ( bit_is_clear(PINB, PB6) )
{
_delay_ms(PUSHDELAYPOLL);
pushtime++;
}

//***if glitch pushtime still zero here !

// check push time
if (pushtime > TRESHOLDOFF)
{
///***long hold means goto power down***
/// turn off zerocross INT
/// for NO wackup from powerdown
DISABLEPCINT;

/// no triac pulse needed
UNMASKTRIAC;

/// INT0 back on
/// for wackup from powerdown
ENABLEINT0;

/// powerdown initiated
sleep_mode();

/// zerocross back on
ENABLEPCINT;

/// triac puls back on
MASKTRIAC;

}
else if (pushtime != ZEROTIME)
{
///***normal hold for triac step***

/// increase one step
triaclevel--;

/// get pre calculated values
TC1H = tc1high[triaclevel];
OCR1A = tc1low [triaclevel];

/// when max goto min
if (triaclevel==TRIACMAX)
triaclevel= TRIACLEVELS;
}

/// toggle INT flag atomic
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
interrupt0 = NOTSIGNALED;
}

/// reset pushtime
pushtime = ZEROTIME;

/// save to trigger again on edge
ENABLEINT0;
}
}

As you can see I work with some threshold value to keep track how long the button has been pressed. This is done to diversify a simple push or a long push which in my case puts the AVR to sleep and put off the lamp completely. This concept works great. Ok I bring you up to the next slave sequel then.




sequel to slave concepts

2.making the gate triac pulses:

So every 20ms there's is a new sinus wave if you have a 50hz frequency distribution. The sinus wave is 50% positive and 50% negative which means also that the positive and negative have a duration of 10ms. The purpose is to let the triac conduct somewhere in these 10ms depending on the wanted duty cycle or lamp brightness. I noticed that the range between 0 -1ms and 9-10ms is not of much use anyway. It's also a fact that light strength (candelas) are not linear at all and have to be converted using some S-curve function (eg 1/1+e^x)

What I did was very simple. On every compare match interrupt ( see previous blog ) I fire a pulse with a wide of 5µs. The time needed for the pulse depends on the triac you use. The 5µs is made by the default avr lib delay function. At the end of the interrupt I put the PCINT back on again to catch the next zero crossing. See code snippet below:

ISR(TIMER1_COMPA_vect)
{
SETTRIAC;
_delay_us(TRIACPULSEWIDTH);
CLRTRIAC;
ENABLEPCINT;
}

That's basically it. So if you let say fire your pulse at 5ms you get 50% light intensity if you take 2ms you get 90% and finally 8ms you get 10%. Beware here that the light intensity is inverse equal on the fire time. Again if you really want to have a fluent light distribution you have to implement a S-curve.

Saturday, 7 March 2009

slave concepts


The purpose of the slave AVR is :

  1. zero cross detection

  2. making the gate triac pulses

  3. handling button actions

  4. handling one wire protocol with master

I will go over each of them now in order and explain what I did and found out.

1. zero cross detection:

The input for the zero cross is an opto coupler connected to the rectified and reduced (by zener diode) mains. Every time the sinus crosses the zero the opto react upon it. This signal is given to an input pin of the slave AVR and looks like the picture below:
Basically I implemented this on the AVR using a PCINT (pin change interrupt). First thing to do is disable the ints because otherwise you get two triggers. After that restart a timer to keep track that this was the zero cross and starts counting from there. Pretty simple :

ISR(PCINT_vect)

{

DISABLEPCINT;

RESTARTTIM1;

}

The main clock of the AVR was feed by a 12.8MHZ (1 ppm ) crystal. So the timer settings were:

void SetTimerTriac (void)

{
/// TIMER 1 enable fast PWM mode on OCR1A
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(PWM1A);

/// TIMER 1 prescale value 128
TCCR1B = _BV(CS13);

/// TIMER 1 interrupt mask compare match OCR1A
TIMSK = _BV(OCIE1A);

/// TIMER 1 TOP value OCR1C
/// 0x03E8-1 or 1000 units
TC1H = 0x03;

OCR1C = 0xE7;

/// TIMER 1 compare match value OCR1A
TC1H = tc1high[triaclevel];
OCR1A = tc1low [triaclevel];

/// TIMER 1 starting point
TC1H = 0;
TCNT1 = 0;


}

recap

It's a very long time now since I blogged here. I was to busy working on the concepts actually. But i'm back again as I never give up you know by now. Let me first recapitulate what the my intentions were:

I now have a domotic system running for three years on a couple of AVRs. The core system is quit good and very stable. But it was foreseen to have a link with my local network and even beyond. This was accomplished in using a serial2TCP converter of multitech. And this is exactly the point where things went wrong. The multitech pcb sucks with a power of 100 ! It's nothing but consequent in his interfacing and the quality of the electronics are equally bad too. After a year the power supply section was not surprisingly dead as hell. So my system continued to run, but without a possibility to change things on the fly as changing light connections or timer programs for the heater. I said to myself "this was a very bad decision made on a monday morning after having a hard weekend". This was the time that I started to think all over again with the idea that next time (third system must be the goody one) my system needs to be almost perfect. I have a period behind me now of almost 2 years of experimenting and thinking as you can read on my blogs. So it becomes time to make a final concept now don't you think ? Well I can say that I have my final concept ready !

I will slowly introduce you to my final workouts in my next blogs which I also write this weekend.


Wednesday, 28 January 2009

new pcb ready























Finally the pcb with mirrored oled display is finished !

Meanwhile I did a lot of try outs with proof of concepts. As you can see one of them was the oled display. But I will treat a few proof of concepts in the next blogs.

TRIOS ROCKS !



Saturday, 20 December 2008

development kit ready

It's just a pitty that the connector of the display is mirrored. That's the only thing that went wrong in the process. But we corrected this awful bug and expect a new PCB ready for end of januari 2009.

As you can see the board is totally supplied by the USB cable.

Meanwhile I can continue on this board with further proof of concepts needed for the project.


Things todo:

  1. Writing a serial communication driver for the master
  2. Writing a timer (PWM) based module for the triac
  3. Introduce a button to change the triac state
  4. Set up a parameter structure
  5. Analyse the possibility to filter the CAB signal by software
  6. Expand the one line protocol to the slave state machine
  7. Convert the assembler OLED init code to a C module
  8. Writing a UI on the OLED
  9. Several tests on each of the above
Plenty things still to do as you can see but I love to dive into of course. 
Stay tuned for more news...

Sunday, 30 November 2008

Development kit drawings


Schematics
PCB layout

Components:

1 X ATMEGA644

2 X ATTINY861

1 X 36p display connector 

1 X OLED display

1 X FTDI232 USB2SERIAL

3 X ISP connector

1 X Crystal oscillator 10MHz

1 X Zero crossing input connector

2 X Triac gate output connector

1 X Joystock mini

1 X DC convertor LT1303

1 X Supply stabiliser LD1086 3.3

4 X Led

The PCB and components are ready and ordered. Probably in about 2 weeks the kit is ready for use. Meanly the kit will be used to experiment and prepare the final project. It contains already 2 slaves and 1 master. The final project will have 30 slaves and one master based on the used components on this development kit. So a pretty long way to go. But my intention is that the final project must be ready for 1 july 2009. Stay tuned on this blog where you can follow up the progress and test results of the building blocks.


Friday, 28 November 2008

One wire protocol an exercise

Below the test setup with my new digimess 25Mhz scoop:










After exploring the the basic functionality I wrote my first program. It is an implementation of the Dallas one wire protocol without the possibility to read from the slave. On the picture below you can see a scoop capture. I will need the protocol in my final project so this exercise was worth to do. This protocol is defined in one of my publications and can be found on this link:


(LOWBP.PDF)



We also changed the type of IC for master into ATMEGA644 because this one can be mounted on a DIL feet and is easy to replace instead of using a SMD like one. The development kit drawings are almost finished so I expect it ready for half of December. In the next blog I present the development kit layout.








Sunday, 16 November 2008

Exploring the world of AVR.











Exploring the world of AVR.

This weekend I tested all the functionalities of the AVR atmega8. On the pictures you can see my working environment.The intention was to learn the basics sofware tools like AVR studio 4 and hardware itself. The advantage is that when you learn thison a atmega8 you can easily port your knowledge to the complete series of AVRs.

This weekend I learned:

- INT0/INT1 edge trigger interrupt
- 8 bit timer0 basic skills with overflow interrupt
- 16 bit timer1 with CTC match
- 16 bit timer1 and fast PWM
- 16 bit timer1 PWM phase/frequency correct mode
- ICP mode on pin capturing and counting frequency
- USART streaming from avr GCC
- linking with floating point libs for printf
- sleeping modes

So pretty much everything I guess , I left timer2 because it has the same operational modes.

This was meant to be as a full preparation to the real project. Now it's much easier to give my input for the hardware design of the dev kit.The development kit will be ready at the end of December. Meanwhile I have this great little board already to experiment.

Special thanks to Ronny for that !









Monday, 10 November 2008

TRIOS overview

TRIOS high level architectural overview on whiteboard:


Three big PCBs will be made each containing: - 10 triacs 8A max - 10 AVRtiny low power control MCUs - optionally master controller with lcd Which gives a total of 30 ouputs fully dimmer controlled. One PCB will have a master unit companied with a little OLED lcd module to parametrize the slave modules. The master and the slaves will be connected by a one wire bus. At this stage it's to early to reveal to much details as we are just beginning to explore what target devices could best do the job. However a first proposition is already chosen: Slave : ATTiny861 Master : ATMEGA2560

The hardware will be done by my friend and can be contacted at manes6969atgmail.com
I will write the software using the AVRstudio 4 with gcc plugin.

The first thing we work on now is a development kit that makes live a bit easier and make things more concrete.

Stay tuned there will be much more in the coming weeks.

First prototype


First prototype dimmer based on 8A triac and pulse controlled by an AVRtiny based on zero point detection.
Control pcb is totally separated from the 220V using optoelectronics.