Professionally made jewellery – with less professional content

On the occasion of our fifth wedding anniversary I had this pendant finished – because I stated a year in advance. ^^

Some time before that I had seen Adafruit’s iCufflinks (on hackaday of course). I liked the idea and -as usual- the documentation was online (https://github.com/adafruit/iCufflinks), but it seemed squander to just drive one LED with a microcontroller.

Via Charlieplexing (Wikipedia, perhaps this Instrucable is even more informative) you can drive six LEDs via three tri-state ports. Just like on the first picture here: http://www.elektronik-labor.de/AVR/Charlieplexing.html

…but first I had to get a software-PWM running on a Microchip PIC10F206. (I had no equipment for Atmel comtrollers and more experience with PICs.)

IMG_20120330_085323 IMG_20120330_085658

First code was developed on a PIC10F204, but I switched to a …206 later. Memory is just ridiculously sparse on this 6-Pin-µCs.

;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC10F206. This file contains the basic code               *
;   building blocks to build upon.                                    *
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:	    PICcuff.asm                                       *
;    Date:          30.03.2012                                        *
;    File Version:  0.1                                               *
;                                                                     *
;    Author:        Jan Beckendorf                                    *
;    Company:                                                         *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P10F204.INC, 10f204.lkr                          *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************

	list      p=10F204            ; list directive to define processor
	#include         ; processor specific variable definitions

	__CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

;************************************
; Constants							*
;************************************
LED				EQU		GP0

;************************************
; Variables							*
;************************************
TEMP			EQU		10h
CNT1			EQU		11h
CNT2			EQU		12h
CNT3			EQU		13h
TABLEPOSITION	EQU		14h
BRIGHTNESS		EQU		15h
DARKNESS		EQU		16h
PWMCOUNTER		EQU		17h

;**********************************************************************

;*************************************
;* Cold start						 *
;*************************************

				ORG     0x1FF             ; processor reset vector

; Internal RC calibration value is placed at location 0x1FF by Microchip
; as a movlw k, where the k is a literal value.
; 4 MHz +/- 1% => INTOSC/4 = 1 MHz

				ORG     0x000				; coding begins here
				MOVWF   OSCCAL				; update register with factory cal value
											; "After you move in the calibration constant, do not change the value."
;	1000 000x = Minimum frequency | x = INTOSC/4 Output Enable bit [1 = INTOSC/4 output onto GP2]
				GOTO	INIT
; DEBUG:
				FILL 	(GOTO FORREST), 0x0A

;*************************************
;* Subroutines						 *
;*************************************

; Lookup-Table

LOOKUP
				ADDWF	PCL, F					; Jump to entry specified by "w"
				NOP
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'2'
				RETLW	D'3'
				RETLW	D'5'
				RETLW	D'8'
				RETLW	D'11'
				RETLW	D'15'
				RETLW	D'20'
				RETLW	D'25'
				RETLW	D'30'
				RETLW	D'36'
				RETLW	D'43'
				RETLW	D'49'
				RETLW	D'56'
				RETLW	D'64'
				RETLW	D'72'
				RETLW	D'80'
				RETLW	D'88'
				RETLW	D'97'
				RETLW	D'105'
				RETLW	D'114'
				RETLW	D'123'
				RETLW	D'132'
				RETLW	D'141'
				RETLW	D'150'
				RETLW	D'158'
				RETLW	D'167'
				RETLW	D'175'
				RETLW	D'183'
				RETLW	D'191'
				RETLW	D'199'
				RETLW	D'206'
				RETLW	D'212'
				RETLW	D'219'
				RETLW	D'225'
				RETLW	D'230'
				RETLW	D'235'
				RETLW	D'240'
				RETLW	D'244'
				RETLW	D'247'
				RETLW	D'250'
				RETLW	D'252'
				RETLW	D'253'
				RETLW	D'254'
				RETLW	D'255'
				RETLW	D'254'
				RETLW	D'253'
				RETLW	D'252'
				RETLW	D'250'
				RETLW	D'247'
				RETLW	D'244'
				RETLW	D'240'
				RETLW	D'235'
				RETLW	D'230'
				RETLW	D'225'
				RETLW	D'219'
				RETLW	D'212'
				RETLW	D'206'
				RETLW	D'199'
				RETLW	D'191'
				RETLW	D'183'
				RETLW	D'175'
				RETLW	D'167'
				RETLW	D'158'
				RETLW	D'150'
				RETLW	D'141'
				RETLW	D'132'
				RETLW	D'123'
				RETLW	D'114'
				RETLW	D'105'
				RETLW	D'97'
				RETLW	D'88'
				RETLW	D'80'
				RETLW	D'72'
				RETLW	D'64'
				RETLW	D'56'
				RETLW	D'49'
				RETLW	D'43'
				RETLW	D'36'
				RETLW	D'30'
				RETLW	D'25'
				RETLW	D'20'
				RETLW	D'15'
				RETLW	D'11'
				RETLW	D'8'
				RETLW	D'5'
				RETLW	D'3'
				RETLW	D'2'
				RETLW	D'1'
				RETLW	D'0'

; Catch jumps out of programm here
FORREST
				MOVLW	B'11111110'
				TRIS	GPIO
				BSF		GPIO, GP0
				BSF		GPIO, GP0
				BSF		GPIO, GP0
				BCF		GPIO, GP0
				GOTO	FORREST
				FILL 	(GOTO FORREST), 0x0A

;************************************
; Initialization					*
;************************************

INIT
;				CLRWDT						; Watchdog not in use
				MOVLW	B'11000010'			; Set OPTION register
;						  ||||||||
;						  |||||||+---------------------->	\
;						  ||||||+----------------------->	 | PS: Prescaler Rate Select bits [Timer0: 1...256, WDT: 1...128]
;						  |||||+------------------------>	/  INTOSC/4 = 1 MHz => 1000...3,9 kHz
;						  ||||+------------------------->	PSA: Prescaler Assignment bit [1 = Prescaler assigned to the WDT]
;						  |||+-------------------------->	T0SE: Timer0 Source Edge Select bit [0 = low => high]
;						  ||+--------------------------->	T0CS: Timer0 Clock Source Select bit [0 = FOSC / 4]
;						  |+---------------------------->	/GPPU: Enable Weak Pull-ups bit (GP0, GP1, GP3)  [1 = Disabled]
;						  +----------------------------->	/GPWU: Enable Wake-up on Pin Change bit (GP0, GP1, GP3) [1 = Disabled]
				OPTION

				MOVLW	B'11110111'			; Set (disable) comparator module
;						  ||||||||
;						  |||||||+---------------------->	/CWU: Comparator Wake-up on Change Enable bit [1 = Disabled]
;						  ||||||+----------------------->	CPREF: Comparator Positive Reference Select bit [1 = CIN+ pin]
;						  |||||+------------------------>	CNREF: Comparator Negative Reference Select bit [1 = CIN- pin]
;						  ||||+------------------------->	CMPON: Comparator Enable bit [0 = Disabled]
;						  |||+-------------------------->	/CMPT0CS: Comparator TMR0 Clock Source bit [1 = selected by T0CS control bit]
;						  ||+--------------------------->	POL: Comparator Output Polarity bit [1 = Output of comparator not inverted]
;						  |+---------------------------->	/COUTEN: Comparator Output Enable bit [1 = Output of comparator is NOT placed on the COUT pin]
;						  +----------------------------->	CMPOUT: Comparator Output bit
				MOVWF	CMCON0

				CLRF	GPIO				; Clear I/O register
				MOVLW	B'11111110'
				TRIS	GPIO				; Output Driver Control => High-Impedance mode on GP1 & GP2

				MOVLW	D'1'
				MOVWF	TABLEPOSITION

				GOTO	MAIN

;*************************************
;* Hauptprogramm					 *
;*************************************

MAIN
				; last entry in table?
				DECFSZ	TABLEPOSITION, F
				GOTO	CONTINUE
				; reload value
				MOVLW	D'91'				; no. ob values in lokup table
				MOVWF	TABLEPOSITION
CONTINUE
				MOVLW	0xFF
				MOVWF	DARKNESS
				; load next led brightness
				MOVF	TABLEPOSITION, W
				CALL	LOOKUP
				MOVWF	BRIGHTNESS			; stay on for [0...255]
				SUBWF	DARKNESS, F			; staf off for [255 - value above]

PWM_INIT
				MOVLW	D'26'
				MOVWF	PWMCOUNTER

PWM_START
				CLRF	TMR0
				BCF		GPIO, GP0
PWM_ON
				MOVF	BRIGHTNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM_ON

				CLRF	TMR0
				BSF		GPIO, GP0
PWM_OFF
				MOVF	DARKNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM_OFF

				DECFSZ	PWMCOUNTER, F
				GOTO	PWM_START

				BCF		GPIO, GP0
				GOTO	MAIN

;********************
;* Ende				*
;********************
				FILL 	(GOTO FORREST), 0xFD-$; Restlichen Speicher mit Sprungbefehl füllen
				END							; directive 'end of program'

I can’t remember, which lookup-table I used here, but the reverse-engineered Apple PWM-values from Adafruit did not quite fit my LEDs. I modified the tables in Excel until they worked for me.

This video shows the breadboard version with one LED:

Most of the programing was done on this stripboard prototype:

The layout was done in TARGET 3001! once everything worked good enough.  As a power source I chose a CR1632.

Schaltplan Entflechtung

Planspiel2Planspiel1

Calling the WAF of this kind of blinkenlights „not particularly high“ would already be a massive exaggeration. Same goes for calling my skills in producing pretty things „not so good“.

But at this time Nicole Kaleske, who already had forged our wedding rings, was regularly tending the bar at my favourite pub – so I could just discuss my ideas with her.

After she immediately showed interest in this, we agreed on what was possible and I could order circuit boards and solder a few samples two weeks later.

DSCN7215 DSCN7213

The PWM then could be optimized to fit the real geometries and behaviour of the LEDs. We went with six red ones to get not too flashy.

IMG_20130905_173033 IMG_20130905_173355

The first picture of the front:

Foto

And here is a quick Video she made:

(I never got to make a better one to demontrate the function.)

And then it was finished. 🙂

Nicole also made a tool to extract the button cell.

IMG_20131014_165213 IMG_20131014_165149

Brilliant! Even the suckling liked it. The dictionary really said suckling“ *lol*

IMG_20131014_165156 P1050848

Re-drawing the schematic in whatever you use should not be hard at all. And here is my latest assembler code for the PIC:


;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC10F206. This file contains the basic code               *
;   building blocks to build upon.                                    *
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:	    xxx.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author:                                                          *
;    Company:                                                         *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P10F206.INC                                      *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************

;#define		CCW

	list      p=10F206            ; list directive to define processor
	#include         ; processor specific variable definitions

	__CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

;************************************
; Constants							*
;************************************
LED				EQU		GP0

;************************************
; Variables							*
;************************************
TEMP			EQU		10h
CNT1			EQU		11h
CNT2			EQU		12h
CNT3			EQU		13h
TABLEPOSITION1	EQU		14h
TABLEPOSITION2	EQU		15h
TABLEPOSITION3	EQU		16h
TABLEPOSITION4	EQU		17h
TABLEPOSITION5	EQU		18h
TABLEPOSITION6	EQU		19h
BRIGHTNESS		EQU		1Ah
DARKNESS		EQU		1Bh
PWMCOUNTER		EQU		1Ch

;************************************
; Macros							*
;************************************

LEDS_OFF		MACRO
				MOVLW	B'11111111'	; GP0...GP2 => Input / high impedance
				TRIS	GPIO
				ENDM

;LEDS_ON			MACRO
;				MOVLW	B'11111000'	; GP0...GP2 => Output
;				TRIS	GPIO
;				ENDM

LED_1_2			MACRO
				MOVLW	B'11111100'	; GP2 => high impedance
				TRIS	GPIO
				ENDM

LED_3_4			MACRO
				MOVLW	B'11111001'	; GP0 => high impedance
				TRIS	GPIO
				ENDM

LED_5_6			MACRO
				MOVLW	B'11111010'	; GP1 => high impedance
				TRIS	GPIO
				ENDM

LED_1_ON		MACRO
#ifdef			CCW
				MOVLW	B'11111101'
#else
				MOVLW	B'11111110'
#endif
				MOVWF	GPIO
				ENDM

LED_1_OFF		MACRO
				MOVLW	B'11111111'
				MOVWF	GPIO
				ENDM

LED_2_ON		MACRO
#ifdef			CCW
				MOVLW	B'11111110'
#else
				MOVLW	B'11111101'
#endif
				MOVWF	GPIO
				ENDM

LED_2_OFF		MACRO
				MOVLW	B'11111111'
				MOVWF	GPIO
				ENDM

LED_3_ON		MACRO
#ifdef			CCW
				MOVLW	B'11111101'
#else
				MOVLW	B'11111011'
#endif
				MOVWF	GPIO
				ENDM

LED_3_OFF		MACRO
				MOVLW	B'11111111'
				MOVWF	GPIO
				ENDM

LED_4_ON		MACRO
#ifdef			CCW
				MOVLW	B'11111011'
#else
				MOVLW	B'11111101'
#endif
				MOVWF	GPIO
				ENDM

LED_4_OFF		MACRO
				MOVLW	B'11111111'
				MOVWF	GPIO
				ENDM

LED_5_ON		MACRO
#ifdef			CCW
				MOVLW	B'11111011'
#else
				MOVLW	B'11111110'
#endif
				MOVWF	GPIO
				ENDM

LED_5_OFF		MACRO
				MOVLW	B'11111111'
				MOVWF	GPIO
				ENDM

LED_6_ON		MACRO
#ifdef			CCW
				MOVLW	B'11111110'
#else
				MOVLW	B'11111011'
#endif
				MOVWF	GPIO
				ENDM

LED_6_OFF		MACRO
				MOVLW	B'11111111'
				MOVWF	GPIO
				ENDM

;*************************************
;* Cold start						 *
;*************************************

				ORG     0x1FF             ; processor reset vector

; Internal RC calibration value is placed at location 0x1FF by Microchip
; as a movlw k, where the k is a literal value.
; 4 MHz +/- 1% => INTOSC/4 = 1 MHz

				ORG     0x000				; coding begins here
				MOVWF   OSCCAL				; update register with factory cal value
											; "After you move in the calibration constant, do not change the value."
;	1000 000x = Minimum frequency | x = INTOSC/4 Output Enable bit [1 = INTOSC/4 output onto GP2]
				GOTO	POR

				FILL 	(GOTO POR), 0x0A

;*************************************
;* Subroutines						 *
;*************************************

; Delays
;DEL_8BIT
;				MOVLW	B'11111111'			;Fill counter into RAM
;				MOVWF	CNT1				;0b11111111 = 0xFF = 255
;D8_WAIT
;				DECFSZ	CNT1, F				;Count RAM 0x10 down to 0
;				GOTO	D8_WAIT				;At 0:
;				RETLW	B'00000000'
;
;DEL_19BIT
;				MOVLW	B'11111111'
;				MOVWF	CNT1
;				MOVWF	CNT2
;				MOVLW	B'00001111'			; Wait 10 instead of 5min!
;				MOVWF	CNT3				; => ca. 1,375s (ctr)
;CNT_19BIT
;				DECFSZ	CNT1, F				;RAM 10 - count to 0
;				GOTO	CNT_19BIT			;Bei 0:
;
;				MOVLW	B'11111111'			;Refresh RAM 10
;				MOVWF	CNT1
;				DECFSZ	CNT2, F				;Decrement RAM 11,
;				GOTO	CNT_19BIT			;at 0:
;;				CLRWDT
;				MOVLW	B'11111111'			;re-fill
;				MOVWF	CNT2
;				DECFSZ	CNT3, F				;Decrement RAM 12,
;				GOTO	CNT_19BIT			;at 0
;
;				RETLW	B'00000000'
;
; Lookup-Table
LOOKUP
				ADDWF	PCL, F					; Jump to entry specified by "w"
				NOP
; sharp rise
				RETLW	D'9'
				RETLW	D'8'
				RETLW	D'7'
				RETLW	D'6'
				RETLW	D'5'
				RETLW	D'4'
				RETLW	D'3'
				RETLW	D'2'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'1'
				RETLW	D'2'
				RETLW	D'3'
				RETLW	D'4'
				RETLW	D'5'
				RETLW	D'6'
				RETLW	D'7'
				RETLW	D'8'
				RETLW	D'9'
				RETLW	D'10'
				RETLW	D'12'
				RETLW	D'14'
				RETLW	D'16'
				RETLW	D'20'
				RETLW	D'24'
				RETLW	D'28'
				RETLW	D'34'
				RETLW	D'39'
				RETLW	D'44'
				RETLW	D'51'
				RETLW	D'59'
				RETLW	D'71'
				RETLW	D'86'
				RETLW	D'105'
				RETLW	D'128'
				RETLW	D'154'
				RETLW	D'182'
				RETLW	D'210'
				RETLW	D'233'
				RETLW	D'249'
				RETLW	D'254'
				RETLW	D'246'
				RETLW	D'228'
				RETLW	D'201'
				RETLW	D'170'
				RETLW	D'138'
				RETLW	D'110'
				RETLW	D'86'
				RETLW	D'68'
				RETLW	D'54'
				RETLW	D'45'
				RETLW	D'38'
				RETLW	D'34'
				RETLW	D'28'
				RETLW	D'24'
				RETLW	D'20'
				RETLW	D'16'
				RETLW	D'14'
				RETLW	D'12'
				RETLW	D'10'

				; Catch jumps out of the table here:
				FILL 	(GOTO INIT), 0xA0

;************************************
; Initialization					*
;************************************

POR				; Ensure digital operation of GP2:
				BCF		CMCON0, CMPON
				BSF		CMCON0, NOT_COUTEN
				MOVLW	B'11000001'
				OPTION
				CLRF	GPIO
				MOVLW	B'11111000'
				TRIS	GPIO
				BCF		CMCON0, CMPON
				BSF		CMCON0, NOT_COUTEN
				MOVLW	B'11000001'
				OPTION		

INIT
				MOVLW	B'11111111'
				TRIS	GPIO				; Output Driver Control => High-Impedance mode on GPIO
				MOVLW	B'11111111'
				MOVWF	GPIO

;				CLRWDT						; Watchdog not in use
				MOVLW	B'11000001'			; Set OPTION register
;						  ||||||||
;						  |||||||+---------------------->	\
;						  ||||||+----------------------->	 | PS: Prescaler Rate Select bits [Timer0: 1...256, WDT: 1...128]
;						  |||||+------------------------>	/  INTOSC/4 = 1 MHz => 1000...3,9 kHz
;						  ||||+------------------------->	PSA: Prescaler Assignment bit [1 = Prescaler assigned to the WDT]
;						  |||+-------------------------->	T0SE: Timer0 Source Edge Select bit [0 = low => high]
;						  ||+--------------------------->	T0CS: Timer0 Clock Source Select bit [0 = FOSC / 4]
;						  |+---------------------------->	/GPPU: Enable Weak Pull-ups bit (GP0, GP1, GP3)  [1 = Disabled]
;						  +----------------------------->	/GPWU: Enable Wake-up on Pin Change bit (GP0, GP1, GP3) [1 = Disabled]
				OPTION

				MOVLW	B'11110111'			; Set (disable) comparator module
;						  ||||||||
;						  |||||||+---------------------->	/CWU: Comparator Wake-up on Change Enable bit [1 = Disabled]
;						  ||||||+----------------------->	CPREF: Comparator Positive Reference Select bit [1 = CIN+ pin]
;						  |||||+------------------------>	CNREF: Comparator Negative Reference Select bit [1 = CIN- pin]
;						  ||||+------------------------->	CMPON: Comparator Enable bit [0 = Disabled]
;						  |||+-------------------------->	/CMPT0CS: Comparator TMR0 Clock Source bit [1 = selected by T0CS control bit]
;						  ||+--------------------------->	POL: Comparator Output Polarity bit [1 = Output of comparator not inverted]
;						  |+---------------------------->	/COUTEN: Comparator Output Enable bit [1 = Output of comparator is NOT placed on the COUT pin]
;						  +----------------------------->	CMPOUT: Comparator Output bit
				MOVWF	CMCON0

				MOVLW	D'91';D'1'
				MOVWF	TABLEPOSITION1
				MOVLW	D'76';D'15'
				MOVWF	TABLEPOSITION2
				MOVLW	D'61';D'30'
				MOVWF	TABLEPOSITION3
				MOVLW	D'46';D'45'
				MOVWF	TABLEPOSITION4
				MOVLW	D'31';D'60'
				MOVWF	TABLEPOSITION5
				MOVLW	D'16';D'75'
				MOVWF	TABLEPOSITION6

				MOVLW	B'11111111'
				MOVWF	GPIO
				MOVLW	B'11111111'
				TRIS	GPIO				; Output Driver Control => High-Impedance mode on GPIO

				GOTO	MAIN

				FILL 	(GOTO INIT), 0x0A

;*************************************
;* Main program						 *
;*************************************

MAIN

TAB_POS_1
				; last entry in table?
				DECFSZ	TABLEPOSITION1, F
				GOTO	TAB_POS_2
				; reload value
				GOTO	INIT
;				MOVLW	D'91'				; no. of values in lookup table +1
;				MOVWF	TABLEPOSITION1
TAB_POS_2
				; last entry in table?
				DECFSZ	TABLEPOSITION2, F
				GOTO	TAB_POS_3
				; reload value
				MOVLW	D'91'				; no. of values in lookup table +1
				MOVWF	TABLEPOSITION2
TAB_POS_3
				; last entry in table?
				DECFSZ	TABLEPOSITION3, F
				GOTO	TAB_POS_4
				; reload value
				MOVLW	D'91'				; no. of values in lookup table +1
				MOVWF	TABLEPOSITION3
TAB_POS_4
				; last entry in table?
				DECFSZ	TABLEPOSITION4, F
				GOTO	TAB_POS_5
				; reload value
				MOVLW	D'91'				; no. of values in lookup table +1
				MOVWF	TABLEPOSITION4
TAB_POS_5
				; last entry in table?
				DECFSZ	TABLEPOSITION5, F
				GOTO	TAB_POS_6
				; reload value
				MOVLW	D'91'				; no. of values in lookup table +1
				MOVWF	TABLEPOSITION5
TAB_POS_6
				; last entry in table?
				DECFSZ	TABLEPOSITION6, F
				GOTO	PWM_INIT
				; reload value
				MOVLW	D'91'				; no. of values in lookup table +1
				MOVWF	TABLEPOSITION6		

PWM_INIT
				MOVLW	D'8'
				MOVWF	PWMCOUNTER

START_PWM
				LED_1_2

				MOVLW	0xFF
				MOVWF	DARKNESS
				; load next led brightness
				MOVF	TABLEPOSITION1, W
				CALL	LOOKUP
				MOVWF	BRIGHTNESS			; stay on for [0...255]
				SUBWF	DARKNESS, F			; stay off for [255 - value above]

PWM1_START
				CLRF	TMR0
				LED_1_ON
PWM1_ON
				MOVF	BRIGHTNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM1_ON

				CLRF	TMR0
				LED_1_OFF
PWM1_OFF
;				NOP
				MOVF	DARKNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM1_OFF

				MOVLW	0xFF
				MOVWF	DARKNESS
				; load next led brightness
				MOVF	TABLEPOSITION2, W
				CALL	LOOKUP
				MOVWF	BRIGHTNESS			; stay on for [0...255]
				SUBWF	DARKNESS, F			; stay off for [255 - value above]

PWM2_START
				CLRF	TMR0
				LED_2_ON
PWM2_ON
				MOVF	BRIGHTNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM2_ON

				CLRF	TMR0
				LED_2_OFF
PWM2_OFF
;				NOP
				MOVF	DARKNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM2_OFF

				LED_3_4

				MOVLW	0xFF
				MOVWF	DARKNESS
				; load next led brightness
				MOVF	TABLEPOSITION3, W
				CALL	LOOKUP
				MOVWF	BRIGHTNESS			; stay on for [0...255]
				SUBWF	DARKNESS, F			; stay off for [255 - value above]

PWM3_START
				CLRF	TMR0
				LED_3_ON
PWM3_ON
				MOVF	BRIGHTNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM3_ON

				CLRF	TMR0
				LED_3_OFF
PWM3_OFF
;				NOP
				MOVF	DARKNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM3_OFF

				MOVLW	0xFF
				MOVWF	DARKNESS
				; load next led brightness
				MOVF	TABLEPOSITION4, W
				CALL	LOOKUP
				MOVWF	BRIGHTNESS			; stay on for [0...255]
				SUBWF	DARKNESS, F			; stay off for [255 - value above]

PWM4_START
				CLRF	TMR0
				LED_4_ON
PWM4_ON
				MOVF	BRIGHTNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM4_ON

				CLRF	TMR0
				LED_4_OFF
PWM4_OFF
;				NOP
				MOVF	DARKNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM4_OFF

				LED_5_6

				MOVLW	0xFF
				MOVWF	DARKNESS
				; load next led brightness
				MOVF	TABLEPOSITION5, W
				CALL	LOOKUP
				MOVWF	BRIGHTNESS			; stay on for [0...255]
				SUBWF	DARKNESS, F			; stay off for [255 - value above]

PWM5_START
				CLRF	TMR0
				LED_5_ON
PWM5_ON
				MOVF	BRIGHTNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM5_ON

				CLRF	TMR0
				LED_5_OFF
PWM5_OFF
;				NOP
				MOVF	DARKNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM5_OFF

				MOVLW	0xFF
				MOVWF	DARKNESS
				; load next led brightness
				MOVF	TABLEPOSITION6, W
				CALL	LOOKUP
				MOVWF	BRIGHTNESS			; stay on for [0...255]
				SUBWF	DARKNESS, F			; stay off for [255 - value above]

PWM6_START
				CLRF	TMR0
				LED_6_ON
PWM6_ON
				MOVF	BRIGHTNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM6_ON

				CLRF	TMR0
				LED_6_OFF
PWM6_OFF
;				NOP
				MOVF	DARKNESS, W
				SUBWF	TMR0, W
				BTFSS	STATUS, C
				GOTO	PWM6_OFF

				DECFSZ	PWMCOUNTER, F
				GOTO	START_PWM

				GOTO	MAIN

;********************
;* End				*
;********************

				FILL 	(GOTO INIT), 0x1FD-$; Fill the rest of the memory
				END							; directive 'end of program'

…but be warned that crafting this kind of jewellery is not straightforward. Any goldsmith charging his or her hourly rate will give you a quotation with at least four digits before the comma (€).

(Original post: http://www.metalforum-owl.de/viewtopic.php?f=21&t=138&start=260#p67238, December 1st 2014)

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.