Difference between revisions of "Simple Embedded System Project"

From Embedded Systems Learning Academy
Jump to: navigation, search
(Challenges & Hints)
(LED Strip)
 
(114 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
== Objective ==
 
== Objective ==
Work together as a class to create a wireless network of interactive devicesAn example would be one controller responsible for lights, another controller responsible for motion sensor, and a central control can interact with these controllers to perform tasks such as turning on lights when motion has been detected.
+
Work together as a group to create an LED lighting systemYou will create hardware that controls power to a 12v LED light (or LED strip), and then write the software to control the LED light.
  
Your board contains wireless mesh network allowing you to freely connect many boards together and they can all communicate with each other.  You will exploit this capability to do something creative, and ultimately learn, and have fun.
+
Think outside the box; you can do much more :
 +
*  You can create an alarm clock and turn on LEDs on/off
 +
*  Orientation or rotation can turn on/off lights or change colors.
 +
* You can combine your group with another group to make your project look better!
  
Think outside the box; you can do much more than the examples given :
+
Note that your board contains wireless mesh network allowing you to freely connect many boards together and they can all communicate with each other. This can be useful if you wish to earn extra credit by interacting with multiple boardsFor example, a motion sensor on one board can turn on the lights on multiple boardsThe API is documented at your board's wikipedia page.
* A commander can be programmed as an alarm clock.
 
* A remote node can be connected to a motor that turns sprays water to wake up a person upon an alarm :)
 
*  You can create "Christmas Lights" which has a bunch of lights connected over wireless network.
 
*: Each light sensor node can control an LED strip not just one LED.
 
  
[[File:cmpe_proj_wireless_nodes.png|right|frame|link=Sample Wireless Nodes]]
+
== Tools Needed ==
 +
# Wire wrapping tool - https://www.youtube.com/watch?v=8SSOKppwpAE
 +
# Wire wrapping wire - http://www.adafruit.com/product/1446
 +
# LED strip
 +
# 12 V Power Supply
 +
# SJOne Board(s)
 +
# Resistors
 +
# MOSFET
  
== Structure ==
+
== Connecting the MOSFET ==
There are minimum three nodes to be designed by a team of 6; you can add more nodes and more people in a team if you project is challenging enough. Each team is then split into smaller sub-team for the design of each of the nodes. Each team will also compete with the other teams in your class and your grade will be assigned relative to each other with the best team earning the best grade.
+
Read the datasheet for the MOSFET - http://www.mouser.com/ds/2/308/on%20semiconductor_ntd5865n-d-327059.pdf
 +
 
 +
[[File:Cmpe30_Mosfet_Pin_Connections.JPG]]
 +
 
 +
Also, [http://www.falstad.com/circuit/#%24+1+5.0E-6+10.20027730826997+50+5.0+50%0Af+288+240+384+240+0+1.5%0Ar+288+240+288+336+0+10000.0%0Aw+384+336+384+256+0%0Ag+384+336+384+384+0%0AR+384+112+384+80+0+0+40.0+12.0+0.0+0.0+0.5%0Ar+240+240+240+304+0+1000.0%0A162+240+304+240+336+1+2.1024259+1.0+0.0+0.0%0Ag+288+336+288+384+0%0Ag+240+336+240+384+0%0Aw+240+240+288+240+0%0AL+240+240+176+240+0+0+false+5.0+0.0%0Ax+112+322+223+325+0+12+This+LED+is+optional%0Ax+119+195+221+201+0+24+GPIO+Pin%0Ax+405+247+550+250+0+12+Note+D%2CG%2CS+pin+of+MOSFET%0Ar+384+112+384+176+0+100.0%0A162+384+176+384+224+1+2.1024259+1.0+0.0+0.0%0Ax+404+132+593+135+0+12+Calculate+R+value+based+on+Power%0Ax+94+223+247+229+0+24+Click+to+toggle%0A Please click on this demonstration link], and wire-up the GATE, SOURCE, and DRAIN as demonstrated.  More details are '''[[GPIO Interface | at this article]]'''
 +
 
 +
== LED Strip ==
 +
Current limiting resistors as shown in circuit may not be needed if using LED strip instead of single LED.
 +
LED strip usually has 2 wires: one for supply (12V) and the other for ground. If you have an RGB LED strip, it will have 4 wires Power supply, Red, Green and Blue. All the Red, Green and Blue are Grounds. Ground the color that you want to use: example: Ground RED to turn on LED strip as RED. Ground all the three colors to get white.
 +
 
 +
Do NOT use strips that are longer than a meter. cut them to required length before using.
 +
 
 +
 
 +
LED strips: http://www.adafruit.com/search?q=LED+strip&b=1
  
Each '''sub-team of 2''' should take ownership of what they will do. You '''shall not''' share the code with each other; but instead just list out "how" you can communicate. Here are a couple of examples that show how you can list your communication protocol:
+
== Power Supply ==
 +
Purchase a 12V/2A adaptor. Cut the power cord at a suitable length to reveal Power and ground lines. Use wire wrapping to connect these lines to the circuit.
  
{| class="wikitable"
+
Alternate way: Purchase this (http://www.adafruit.com/product/368) component and use wires to connect to the + and - terminals .
!colspan="2"| Lights Wireless Protocol
 
|-
 
| Wireless Channel
 
| 2580
 
|-
 
| Wireless bitrate
 
| 250
 
|-
 
| Wireless Address
 
| 110
 
|-
 
!colspan="2"| Command List
 
|-
 
| Lights ON
 
| Send 1 byte with value 1
 
|-
 
| Lights OFF
 
| Send 2
 
|-
 
| Lights Auto
 
| Send 3
 
|}
 
  
{| class="wikitable"
+
== Connections ==
!colspan="3"| Sensor Node Wireless Protocol
+
The connections for an LED, MOSFET, board and power supply are shown below:
|-
+
[[File:project_schematic.png|500px]]
| Wireless Channel
 
| 2580
 
|-
 
| Wireless bitrate
 
| 250
 
|-
 
| Wireless Address
 
| 125
 
|-
 
!colspan="3"| Command List
 
|-
 
| Get Light Sensor
 
| Send 1 byte with value 1
 
|  2-byte data returned as uint16_t
 
|-
 
| Get Temperature Sensor
 
| Send 1 byte with value 2
 
|  2-byte data returned as int16_t
 
|}
 
  
A good suggestion to follow is that the commander node always initiates communication and other nodes only "speak when spoken to".  This can generally simplify your project.  When the light sensor receives a byte with the chosen values, you can send a packet back to the sender. Each packet sent receives an acknowledgement back, so ask your lab instructor how you can send back the acknowledgment packet with your sensor data.  This will only require two packets (instead of four), one to request for data, and one for acknowledgment with your sensor data.
+
All connections can be made using the wire wrapping tool. A video describing wire wrapping procedure is given above under the Tools needed section.
  
== Example Nodes ==
+
== Electronic Parts Companies and Useful Engineering Resources ==
The nodes listed below are just examples. You can and should create your own node with its own purpose that goes above and beyond the examples listed in this article. Four unique features are required per node, and some hints are provided in the latter part of this document.  '''Do not worry about the "how"; let the class instructors help you.  Just think about the "what"'''.
+
http://www.socialledge.com/sjsu/index.php?title=Electronic_Parts_Companies_and_Useful_Engineering_Resources
  
=== Lights Node ===
+
== Using the SJOne Board and connecting external components ==
This node shall act like a wireless node that is responsible to turn on and off lights. This will involve some hardware design such that you can connect your board to some high-power LEDs.  Look-up “super bright led” at sparkfun.com for examples.
+
http://www.socialledge.com/sjsu/index.php?title=SJ_One_Board
  
=== Sensor Node ===
+
This page also has a section for using wireless communication between multiple SJOne boards. In order to use the wireless functionality, an SMA connector needs to be soldered on the board. An antenna can be attached to the SMA connector.
This node shall act like a sense point for the commander node. The objective is not just to provide the on-board sense points such as temperature and light, but also implement features such that you can report other creative sense points such as a motion sensor, and distance sensor.
 
  
=== Commander Node ===
+
== Structure ==
This node shall be responsible to put it all together and serve as a single commanding node to get sensor input and control the lights. This node shall provide the interface for the user, so try to provide user options to configure features such as automatic lights, or remote controlled operation.
+
For simplicity, the minimum requirement is that a team of three is able to have control for an LED strip. It has to be interactive, for example: turning on the LEDs upon light sensor or another trigger.
  
 
<BR/>
 
<BR/>
Line 82: Line 60:
 
== Requirements ==
 
== Requirements ==
 
=== Technical ===
 
=== Technical ===
* You must use a '''<code>switch / case </code>''' code section in your code.
+
Your grade will depend on how well you follow the following requirements :
* You must use a state machine in you code.
+
# You must use a '''<code>switch / case </code>''' code section in your code.
*:  This could be as simple as a state machine for "Manual Lights" vs. "Automatic Lights"
+
# You must use a state machine in at least one of your nodes.
* You must utilize functions that use pass-by-value and pass-by-reference.
+
#:  This could be as simple as a state machine for "Manual Lights" vs. "Automatic Lights"
* Project should be self-contained
+
#  All functions used shall be no larger than 50 lines of code.
**  Project should be enclosed, with no wires visible.
+
#:  Split into smaller sub-functions.
**  Project should operate either by a battery or USB power, but NOT require a computer's USB port.
+
# You must utilize functions that use pass-by-value and pass-by-reference.
**:  Should not require the Hercules Terminal to operate
+
# Project should be self-contained
**  All buttons should be labeled.
+
#*  Project should be enclosed, with no wires visible.
 +
#*  Project should not require the Hercules Terminal to operate.
 +
#Project should preferably operate with its own independent power source (or battery pack).
 +
# All buttons should be labeled.
 +
#:  An operator should be able to operate without reading an instruction manual.
  
=== Deliverables ===
+
=== Items to Submit ===
 
At the end of the project, the following items need to be submitted :
 
At the end of the project, the following items need to be submitted :
 
*  Full source-code of all the projects
 
*  Full source-code of all the projects
Line 99: Line 81:
  
 
==== Project Report ====
 
==== Project Report ====
You must submit a full, documented report for your project.  The following are minimum sections required in your PDF submitted report:
+
You must submit a full, documented report for your project (one per group of six).  The following are minimum sections required in your PDF submitted report:
* Introduction
+
# Introduction
*: What does your project do?
+
#*  What does your project do?
*: Try to sell your project in this section.
+
#*  Try to sell your project in this section.
*  Schematics
+
#*  Add a sub-section called "Features & Communication Table"
*: List the hardware you used.
+
#*:  List the features of each node and the communication table.
*: Use "LibreOffice Draw" to draw the schematics
+
#*:  At least four unique features per node should be listed.
* Implementation
+
# Schematics
*: Show your software workings using a flow-chart
+
#*  List the hardware you used.
*: Use bullets and pictures to show the "how" part.
+
#*  Use "LibreOffice Draw" to draw the schematics
*: Discuss the nodes, and their wireless protocol (table of commands).
+
# Implementation
* Testing
+
#*  Show your software workings using a flow-chart
*: What kind of tests did you perform?
+
#*  Use bullets and pictures to show the "how" part.
*: What kind of problems did you solve?
+
#Show what Software you used to control your Hardware.
* Conclusion
+
# Testing
*: What did you learn?
+
#*  What kind of tests did you perform?
*: What worked, and what didn't work?
+
#*  What kind of problems did you solve?
*: How would you improve your project?
+
# Conclusion
 +
#*  What did you learn?
 +
#*  What worked, and what didn't work?
 +
#*  How would you improve your project?
  
 
<BR/>
 
<BR/>
Line 124: Line 109:
  
 
*  How will you design your project to be user friendly?
 
*  How will you design your project to be user friendly?
*  How will you collaborate in your large team?
+
*  How will you collaborate in your team?
 
*  How will you balance your budget and keep parts cost to a minimum?
 
*  How will you balance your budget and keep parts cost to a minimum?
*  How will you design your network protocol such that each team understands a command and response system well?
 
 
*  How will you make your project more creative?  How will it stand out?
 
*  How will you make your project more creative?  How will it stand out?
*  What if you command a light output node that is not responding?
 
*:  How will you report this to the user and what would you do?
 
 
=== Wireless ===
 
As of the wireless mesh network's version 1 source code, the wireless packet can be 32-bytes long, out of which 8 bytes are used by the network header and 24 bytes are free to be used.  Please take a look at the '''<code>mesh_packet_t</code>''' structure to understand the data of the wireless packet.
 
 
[[File:mesh_packet.jpg|center|frame|link=Wireless Mesh Network]]
 
 
=== Debugging Techniques ===
 
*  For the commander, implement a "ping" packet that is sent to everyone once a second.
 
*:  If an ACK is received, turn on an LED, otherwise turn it off (one LED per remote node).
 
*:  This will immediately help diagnose connection issues.
 
*  Any security ?
 
**  What if I get on your network and sabotage your project?
 
**  Can you implement a method such that a command is not so easy for anyone to send?
 
*  Beware of Mr. Sabotage :
 
** In your class, there will be an attacker, which will use "replay attack" technique to attack your project.
 
** Mr. Sabotage will hop from one channel to another to look for presence of the wireless data.
 
** If Mr. Sabotage can read a packet, it will replay it back randomly to confuse your project.
 
 
<BR/>
 
 
== Sample Code ==
 
'''Important Note'''
 
You need to open up '''sys_config.h''' and change your '''WIRELESS_CHANNEL''' to a unique frequency.  This will avoid data collisions between you and other groups.  Each of your nodes should also configure the '''WIRELESS_NODE_ADDR''' to further avoid wireless data collisions.  If you change the '''sys_config.h''' file, you should also perform '''Project'''-->'''Clean''' and rebuild your software code.
 
 
 
=== Light Sensor Node ===
 
<syntaxhighlight lang="c">
 
#include "wireless.h"
 
 
void process_command(char command);
 
 
int main(void)
 
{
 
    char our_addr = 100;
 
    mesh_set_node_addr(our_addr);
 
 
    while (1) {
 
        /* Check if we get a packet within 1 second : */
 
        mesh_packet_t pkt;
 
        if (wireless_get_rx_pkt(&pkt, 1000)) {
 
            /* Assuming first data byte is our command: */
 
            process_command(pkt.data[0]);
 
        }
 
    }
 
    return 0;
 
}
 
 
void process_command(char command)
 
{
 
    enum {
 
        lights_on = 1;
 
        lights_off = 2;
 
    }
 
 
    switch(command) {
 
        case lights_on:
 
            /* TODO Turn on lights */
 
        break;
 
 
        case lights_off:
 
            /* TODO Turn off lights */
 
        break;
 
 
        default:
 
            /* TODO Take action for invalid command */
 
        break;
 
    }
 
}
 
</syntaxhighlight>
 
 
<BR/>
 
 
=== Commander Node ===
 
<syntaxhighlight lang="c">
 
#include "wireless.h"
 
 
int main(void)
 
{
 
    /* Same enum as lights controller */
 
    enum {
 
        lights_on = 1;
 
        lights_off = 2;
 
    }
 
 
    const char our_addr = 200;
 
    const char lights_addr = 100;
 
    const char max_hops = 2;
 
    mesh_set_node_addr(our_addr);
 
 
    while (1) {
 
        /* Turn lights on/off every 3 seconds */
 
        char cmd = 0;
 
 
        cmd = lights_on;
 
        wireless_send(lights_addr, mesh_pkt_ack, &cmd, 1, max_hops);
 
        if (wireless_get_ack_pkt(&pkt, 100)) {
 
            // We got an acknowledge from lights_addr
 
        }
 
        else {
 
            printf("ERROR: No acknowledge from %i (lights)\n", lights_addr);
 
        }
 
        delay_ms(3000);
 
 
        cmd = lights_off;
 
        wireless_send(lights_addr, mesh_pkt_ack, &cmd, 1, max_hops);
 
        /* TODO Check if we got an ACK */
 
        delay_ms(3000);
 
    }
 
    return 0;
 
}
 
</syntaxhighlight>
 
 
 
=== Ping! ===
 
<syntaxhighlight lang="c">
 
#include "io.hpp"
 
#include "wireless.h"
 
#include "soft_timer.h"
 
 
 
int main(void)
 
{
 
    const char max_hops = 2;
 
    mesh_packet_t pkt;
 
 
    enum {
 
        our_addr = 100,
 
        lights_addr = 200,
 
        sensor_addr = 210,
 
    };
 
 
    // Use a software timer "object" with 3000ms duration.
 
    SoftTimer ping_timer;
 
    ping_timer.reset(3000);
 
 
    while (1) {
 
        // If timer expires, restart it again and ping everyone.
 
        if (ping_timer.expired()) {
 
            ping_timer.restart();
 
 
            // Send NULL data to the lights node :
 
            wireless_send(lights_addr, mesh_pkt_ack, "\0", 1, max_hops);
 
 
            // Turn LED #1 on or off based on if we get ACK packet within 100ms
 
            if (wireless_get_ack_pkt(&pkt, 100)) {
 
                LE.on(1);
 
            }
 
            else {
 
                LE.off(1);
 
            }
 
        }
 
    }
 
 
    return 0;
 
}
 
</syntaxhighlight>
 
 
 
=== Send+Receive a variable ===
 
You can send data variables from one board to another; the only slight problem you may face is to identify what kind of information the receiver has received.  In the following example, we just check if the receiver has received a 4-byte packet.  To elaborate this, you may want to send data with an identifier, and then the actual data (next example below).  '''Also note that the wireless can only transport 24-bytes through a single packet.'''
 
 
<BR/>
 
<syntaxhighlight lang="c">
 
#include <stdint.h>
 
#include "wireless.h"
 
 
void sender(void)
 
{
 
    uint32_t my_32bit_var = 1234;
 
    wireless_send(addr, mesh_pkt_act, &my_32bit_var, sizeof(my_32bit_var), 2);
 
}
 
 
void receiver(void)
 
{
 
    mesh_packet_t pkt;
 
    if (wireless_get_rx_pkt(&pkt, 100)) {
 
        /* Check if we indeed got the 4 byte packet (size of uint32 is 4 bytes) */
 
        if (sizeof(uint32_t) == pkt.data_len) {
 
            uint32_t *my_32bit_var_ptr = (uint32_t*) &(pkt.data[0]);
 
            printf("Value is %i\n", *my_32bit_var_ptr);
 
        }
 
    }
 
}
 
</syntaxhighlight>
 
 
 
<BR/>
 
This example solves the problem of identifying "what" sort of information we are getting from the wireless node.  For example, the sensor node may send light sensor data, and distance sensor data, and we need a way to identify it.  See example below and build-up on it or ask for clarification from your class lecturer.
 
 
<syntaxhighlight lang="c">
 
#include <stdint.h>
 
#include "wireless.h"
 
 
/* Sender will send a packet with multiple variables */
 
void sender(void)
 
{
 
    uint8_t pkt_id = 1;
 
    uint32_t var1 = 123;
 
    float var2 = 1.23;
 
 
    /* Create the packet.  See docs of wireless_form_packet() */
 
    mesh_packet_t pkt;
 
    uint8_t hops = 1;
 
    wireless_form_pkt(addr, mesh_pkt_ack, &pkt, hops,
 
                      3,
 
                      &pkt_id, sizeof(pkt_id),
 
                      &var1, sizeof(var1),
 
                      &var2, sizeof(var2));
 
 
    /* TODO Should probably check if packet was formed correctly before sending */
 
    wireless_send_formed_pkt(&pkt);
 
}
 
 
void receiver(void)
 
{
 
    mesh_packet_t pkt;
 
    if (wireless_get_rx_pkt(&pkt, 100)) {
 
 
        /* Check packet type before we access the data */
 
        if (1 == pkt.data[0]) {
 
            uint32_t var1 = 0;
 
            float var2 = 0;
 
            wireless_deform_pkt(&pkt, 3,
 
                                NULL, sizeof(uint8_t), /* Skip 1st byte which was ID */
 
                                &var1, sizeof(var1),  /* 2nd data was uint32_t from sender() */
 
                                &var2, sizeof(var2));  /* 3rd data was float from sender */
 
        }
 
    }
 
}
 
</syntaxhighlight>
 

Latest revision as of 22:37, 21 November 2014

Objective

Work together as a group to create an LED lighting system. You will create hardware that controls power to a 12v LED light (or LED strip), and then write the software to control the LED light.

Think outside the box; you can do much more :

  • You can create an alarm clock and turn on LEDs on/off
  • Orientation or rotation can turn on/off lights or change colors.
  • You can combine your group with another group to make your project look better!

Note that your board contains wireless mesh network allowing you to freely connect many boards together and they can all communicate with each other. This can be useful if you wish to earn extra credit by interacting with multiple boards. For example, a motion sensor on one board can turn on the lights on multiple boards. The API is documented at your board's wikipedia page.

Tools Needed

  1. Wire wrapping tool - https://www.youtube.com/watch?v=8SSOKppwpAE
  2. Wire wrapping wire - http://www.adafruit.com/product/1446
  3. LED strip
  4. 12 V Power Supply
  5. SJOne Board(s)
  6. Resistors
  7. MOSFET

Connecting the MOSFET

Read the datasheet for the MOSFET - http://www.mouser.com/ds/2/308/on%20semiconductor_ntd5865n-d-327059.pdf

Cmpe30 Mosfet Pin Connections.JPG

Also, Please click on this demonstration link, and wire-up the GATE, SOURCE, and DRAIN as demonstrated. More details are at this article

LED Strip

Current limiting resistors as shown in circuit may not be needed if using LED strip instead of single LED. LED strip usually has 2 wires: one for supply (12V) and the other for ground. If you have an RGB LED strip, it will have 4 wires Power supply, Red, Green and Blue. All the Red, Green and Blue are Grounds. Ground the color that you want to use: example: Ground RED to turn on LED strip as RED. Ground all the three colors to get white.

Do NOT use strips that are longer than a meter. cut them to required length before using.


LED strips: http://www.adafruit.com/search?q=LED+strip&b=1

Power Supply

Purchase a 12V/2A adaptor. Cut the power cord at a suitable length to reveal Power and ground lines. Use wire wrapping to connect these lines to the circuit.

Alternate way: Purchase this (http://www.adafruit.com/product/368) component and use wires to connect to the + and - terminals .

Connections

The connections for an LED, MOSFET, board and power supply are shown below: Project schematic.png

All connections can be made using the wire wrapping tool. A video describing wire wrapping procedure is given above under the Tools needed section.

Electronic Parts Companies and Useful Engineering Resources

http://www.socialledge.com/sjsu/index.php?title=Electronic_Parts_Companies_and_Useful_Engineering_Resources

Using the SJOne Board and connecting external components

http://www.socialledge.com/sjsu/index.php?title=SJ_One_Board

This page also has a section for using wireless communication between multiple SJOne boards. In order to use the wireless functionality, an SMA connector needs to be soldered on the board. An antenna can be attached to the SMA connector.

Structure

For simplicity, the minimum requirement is that a team of three is able to have control for an LED strip. It has to be interactive, for example: turning on the LEDs upon light sensor or another trigger.


Requirements

Technical

Your grade will depend on how well you follow the following requirements :

  1. You must use a switch / case code section in your code.
  2. You must use a state machine in at least one of your nodes.
    This could be as simple as a state machine for "Manual Lights" vs. "Automatic Lights"
  3. All functions used shall be no larger than 50 lines of code.
    Split into smaller sub-functions.
  4. You must utilize functions that use pass-by-value and pass-by-reference.
  5. Project should be self-contained
    • Project should be enclosed, with no wires visible.
    • Project should not require the Hercules Terminal to operate.
    • Project should preferably operate with its own independent power source (or battery pack).
  6. All buttons should be labeled.
    An operator should be able to operate without reading an instruction manual.

Items to Submit

At the end of the project, the following items need to be submitted :

  • Full source-code of all the projects
  • Individual evaluations about team members and their contribution
    This will be confidential, and you can submit as one per person (at Canvas).

Project Report

You must submit a full, documented report for your project (one per group of six). The following are minimum sections required in your PDF submitted report:

  1. Introduction
    • What does your project do?
    • Try to sell your project in this section.
    • Add a sub-section called "Features & Communication Table"
      List the features of each node and the communication table.
      At least four unique features per node should be listed.
  2. Schematics
    • List the hardware you used.
    • Use "LibreOffice Draw" to draw the schematics
  3. Implementation
    • Show your software workings using a flow-chart
    • Use bullets and pictures to show the "how" part.
    • Show what Software you used to control your Hardware.
  4. Testing
    • What kind of tests did you perform?
    • What kind of problems did you solve?
  5. Conclusion
    • What did you learn?
    • What worked, and what didn't work?
    • How would you improve your project?


Challenges & Hints

Challenges

Over the course of the project, you will encounter some real-world problems such as :

  • How will you design your project to be user friendly?
  • How will you collaborate in your team?
  • How will you balance your budget and keep parts cost to a minimum?
  • How will you make your project more creative? How will it stand out?